Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
admin
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
8b5740d0
authored
Nov 07, 2024
by
GoldenZqqq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 工作流发起页面-需要自定义选择审批人的节点改为在右侧timeline组件中跳出弹窗选择
parent
92314ee9
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
68 additions
and
161 deletions
+68
-161
src/components/UserSelectForm/index.vue
+16
-8
src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue
+20
-60
src/views/bpm/processInstance/create/mock.ts
+0
-86
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
+32
-7
No files found.
src/components/UserSelectForm/index.vue
View file @
8b5740d0
...
...
@@ -15,7 +15,7 @@
</el-col>
<el-col
:span=
"17"
:offset=
"1"
>
<el-transfer
v-model=
"selectedUserList"
v-model=
"selectedUser
Id
List"
filterable
filter-placeholder=
"搜索成员"
:data=
"userList"
...
...
@@ -24,7 +24,12 @@
</el-col>
</el-row>
<template
#
footer
>
<el-button
:disabled=
"formLoading"
type=
"primary"
@
click=
"submitForm"
>
确 定
</el-button>
<el-button
:disabled=
"formLoading || !selectedUserIdList?.length"
type=
"primary"
@
click=
"submitForm"
>
确 定
</el-button
>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
...
...
@@ -36,21 +41,24 @@ import * as UserApi from '@/api/system/user'
defineOptions
({
name
:
'UserSelectForm'
})
const
emit
=
defineEmits
<
{
confirm
:
[
userList
:
any
[]]
confirm
:
[
id
:
any
,
userList
:
any
[]]
}
>
()
const
{
t
}
=
useI18n
()
// 国际
const
deptList
=
ref
<
Tree
[]
>
([])
// 部门树形结构化
const
userList
:
any
=
ref
([])
// 用户列表
const
message
=
useMessage
()
// 消息弹窗
const
selectedUserList
:
any
=
ref
([])
// 选中的用户列表
const
selectedUser
Id
List
:
any
=
ref
([])
// 选中的用户列表
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
formLoading
=
ref
(
false
)
// 表单的加载中
const
activityId
=
ref
()
// 主键id
/** 打开弹窗 */
const
open
=
async
()
=>
{
const
open
=
async
(
id
,
selectedList
?)
=>
{
activityId
.
value
=
id
resetForm
()
deptList
.
value
=
handleTree
(
await
DeptApi
.
getSimpleDeptList
())
await
getUserList
()
selectedUserIdList
.
value
=
selectedList
?.
map
((
item
)
=>
item
.
id
)
// 修改时,设置数据
dialogVisible
.
value
=
true
}
...
...
@@ -71,8 +79,9 @@ const submitForm = async () => {
try
{
message
.
success
(
t
(
'common.updateSuccess'
))
dialogVisible
.
value
=
false
const
emitUserList
=
userList
.
value
.
filter
((
user
)
=>
selectedUserIdList
.
value
.
includes
(
user
.
id
))
// 发送操作成功的事件
emit
(
'confirm'
,
selectedUserList
.
value
)
emit
(
'confirm'
,
activityId
.
value
,
emitUserList
)
}
finally
{
formLoading
.
value
=
false
}
...
...
@@ -80,13 +89,12 @@ const submitForm = async () => {
const
resetForm
=
()
=>
{
deptList
.
value
=
[]
userList
.
value
=
[]
selectedUserList
.
value
=
[]
selectedUser
Id
List
.
value
=
[]
}
/** 处理部门被点击 */
const
handleNodeClick
=
async
(
row
:
{
[
key
:
string
]:
any
})
=>
{
getUserList
(
row
.
id
)
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
</
script
>
src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue
View file @
8b5740d0
...
...
@@ -19,40 +19,7 @@
v-model=
"detailForm.value"
:option=
"detailForm.option"
@
submit=
"submitForm"
>
<!--
<template
#
type-startUserSelect
>
<el-col
:span=
"24"
>
<el-card
class=
"mb-10px"
>
<template
#
header
>
指定审批人
</
template
>
<el-form
:model=
"startUserSelectAssignees"
:rules=
"startUserSelectAssigneesFormRules"
ref=
"startUserSelectAssigneesFormRef"
>
<el-form-item
v-for=
"userTask in startUserSelectTasks"
:key=
"userTask.id"
:label=
"`任务【${userTask.name}】`"
:prop=
"userTask.id"
>
<el-select
v-model=
"startUserSelectAssignees[userTask.id]"
multiple
placeholder=
"请选择审批人"
>
<el-option
v-for=
"user in userList"
:key=
"user.id"
:label=
"user.nickname"
:value=
"user.id"
/>
</el-select>
</el-form-item>
</el-form>
</el-card>
</el-col>
</template>
-->
</form-create>
</el-col>
<el-col
:span=
"6"
:offset=
"1"
>
...
...
@@ -62,6 +29,8 @@
:activity-nodes=
"activityNodes"
:show-status-icon=
"false"
:startUserSelectTasks=
"startUserSelectTasks"
:startUserSelectAssignees=
"startUserSelectAssignees"
@
select-user-confirm=
"selectUserConfirm"
/>
</el-col>
</el-row>
...
...
@@ -104,8 +73,7 @@ import type { ApiAttrs } from '@form-create/element-ui/types/config'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
*
as
ProcessInstanceApi
from
'@/api/bpm/processInstance'
import
*
as
DefinitionApi
from
'@/api/bpm/definition'
// import * as UserApi from '@/api/system/user'
import
{
activityNodes
as
aN
,
startUserSelectTasks
as
sUs
}
from
'./mock'
// import { activityNodes as aN, startUserSelectTasks as sUs } from './mock'
defineOptions
({
name
:
'ProcessDefinitionDetail'
})
const
props
=
defineProps
<
{
...
...
@@ -122,11 +90,8 @@ const detailForm: any = ref({
})
// 流程表单详情
const
fApi
=
ref
<
ApiAttrs
>
()
// 指定审批人
const
startUserSelectAssigneesFormRef
=
ref
()
// 发起人选择审批人的表单 Ref
const
startUserSelectTasks
:
any
=
ref
([])
// 发起人需要选择审批人的用户任务列表
const
startUserSelectAssignees
=
ref
({})
// 发起人选择审批人的数据
const
startUserSelectAssigneesFormRules
=
ref
({})
// 发起人选择审批人的表单 Rules
// const userList = ref
<
any
[]
>
([])
// 用户列表
const
bpmnXML
:
any
=
ref
(
null
)
// BPMN 数据
/** 当前的Tab */
const
activeTab
=
ref
(
'form'
)
...
...
@@ -139,7 +104,6 @@ const initProcessInfo = async (row: any, formVariables?: any) => {
// 重置指定审批人
startUserSelectTasks
.
value
=
[]
startUserSelectAssignees
.
value
=
{}
startUserSelectAssigneesFormRules
.
value
=
{}
// 情况一:流程表单
if
(
row
.
formType
==
10
)
{
...
...
@@ -164,25 +128,13 @@ const initProcessInfo = async (row: any, formVariables?: any) => {
if
(
processDefinitionDetail
)
{
bpmnXML
.
value
=
processDefinitionDetail
.
bpmnXml
startUserSelectTasks
.
value
=
processDefinitionDetail
.
startUserSelectTasks
startUserSelectTasks
.
value
=
sUs
// 设置指定审批人
// if (startUserSelectTasks.value?.length > 0) {
// detailForm.value.rule.push({
// type: 'startUserSelect',
// props: {
// title: '指定审批人'
// }
// })
// // 设置校验规则
// for (const userTask of startUserSelectTasks.value) {
// startUserSelectAssignees.value[userTask.id] = []
// startUserSelectAssigneesFormRules.value[userTask.id] = [
// { required: true, message: '请选择审批人', trigger: 'blur' }
// ]
// }
// // 加载用户列表
// userList.value = await UserApi.getSimpleUserList()
// }
if
(
startUserSelectTasks
.
value
?.
length
>
0
)
{
for
(
const
userTask
of
startUserSelectTasks
.
value
)
{
// 初始化数据
startUserSelectAssignees
.
value
[
userTask
.
id
]
=
[]
}
}
}
// 情况二:业务表单
}
else
if
(
row
.
formCustomCreatePath
)
{
...
...
@@ -206,19 +158,23 @@ const getApprovalDetail = async (row: any) => {
}
// 获取审批节点,显示 Timeline 的数据
activityNodes
.
value
=
data
.
activityNodes
activityNodes
.
value
=
aN
}
finally
{
}
}
/** 提交按钮 */
const
submitForm
=
async
(
formData
:
any
)
=>
{
debugger
if
(
!
fApi
.
value
||
!
props
.
selectProcessDefinition
)
{
return
}
// 如果有指定审批人,需要校验
if
(
startUserSelectTasks
.
value
?.
length
>
0
)
{
await
startUserSelectAssigneesFormRef
.
value
.
validate
()
for
(
const
userTask
of
startUserSelectTasks
.
value
)
{
if
(
Array
.
isArray
(
startUserSelectAssignees
.
value
[
userTask
.
id
])
&&
startUserSelectAssignees
.
value
[
userTask
.
id
].
length
===
0
)
return
message
.
warning
(
`请选择
${
userTask
.
name
}
的审批人`
)
}
}
// 提交请求
...
...
@@ -245,6 +201,10 @@ const handleCancel = () => {
emit
(
'cancel'
)
}
const
selectUserConfirm
=
(
id
,
userList
)
=>
{
startUserSelectAssignees
.
value
[
id
]
=
userList
?.
map
((
item
)
=>
item
.
id
)
}
defineExpose
({
initProcessInfo
})
</
script
>
...
...
src/views/bpm/processInstance/create/mock.ts
deleted
100644 → 0
View file @
92314ee9
import
{
ProcessInstanceVO
,
User
,
ApprovalTaskInfo
,
ApprovalNodeInfo
}
from
'@/api/bpm/processInstance'
;
import
{
NodeType
}
from
'@/components/SimpleProcessDesignerV2/src/consts'
const
users
:
User
[]
=
[
{
id
:
1
,
nickname
:
'Alice'
,
avatar
:
'https://picsum.photos/200?r=1'
},
{
id
:
2
,
nickname
:
'Bob'
,
avatar
:
'https://picsum.photos/200?r=2'
},
{
id
:
3
,
nickname
:
'Charlie'
,
avatar
:
'https://picsum.photos/200?r=3'
},
{
id
:
4
,
nickname
:
'David'
,
avatar
:
'https://picsum.photos/200?r=4'
}
];
const
approvalTask1
:
ApprovalTaskInfo
=
{
id
:
1
,
ownerUser
:
users
[
0
],
// Alice is the owner (initiator)
assigneeUser
:
users
[
1
],
// Bob is the assignee
status
:
1
,
// In Progress
reason
:
'Please review and approve the request.'
};
const
approvalTask2
:
ApprovalTaskInfo
=
{
id
:
2
,
ownerUser
:
users
[
1
],
// Bob is the owner (approver)
assigneeUser
:
users
[
2
],
// Charlie is the assignee
status
:
0
,
// Pending approval
reason
:
'Awaiting Bob’s decision.'
};
const
approvalTask3
:
ApprovalTaskInfo
=
{
id
:
3
,
ownerUser
:
users
[
2
],
// Charlie is the owner (approver)
assigneeUser
:
users
[
3
],
// David is the assignee
status
:
0
,
// Pending approval
reason
:
'Awaiting Charlie’s decision.'
};
const
approvalNode1
:
ApprovalNodeInfo
=
{
id
:
101
,
name
:
'Start Review'
,
nodeType
:
NodeType
.
START_USER_NODE
,
status
:
1
,
// In Progress
startTime
:
new
Date
(
'2024-11-01T10:00:00Z'
),
tasks
:
[
approvalTask1
]
};
const
approvalNode2
:
ApprovalNodeInfo
=
{
id
:
102
,
name
:
'First Review'
,
nodeType
:
NodeType
.
USER_TASK_NODE
,
status
:
0
,
// Pending approval
startTime
:
new
Date
(
'2024-11-01T11:00:00Z'
),
tasks
:
[
approvalTask2
],
candidateUsers
:
[
users
[
2
],
users
[
3
]]
// Candidate users: Charlie and David
};
const
approvalNode3
:
ApprovalNodeInfo
=
{
id
:
103
,
name
:
'Second Review'
,
nodeType
:
NodeType
.
USER_TASK_NODE
,
status
:
0
,
// Pending approval
startTime
:
new
Date
(
'2024-11-01T12:00:00Z'
),
tasks
:
[
approvalTask3
],
candidateUsers
:
[
users
[
1
],
users
[
3
]]
// Candidate users: Bob and David
};
const
processInstance
:
ProcessInstanceVO
=
{
id
:
1001
,
name
:
'Request Approval Process'
,
processDefinitionId
:
'proc-2024-001'
,
category
:
'Approval Process'
,
result
:
0
,
// Ongoing
tasks
:
[{
id
:
'1'
,
name
:
'Start Review'
},
{
id
:
'2'
,
name
:
'First Review'
},
{
id
:
'3'
,
name
:
'Second Review'
}],
fields
:
[
'field1'
,
'field2'
],
status
:
1
,
// In Progress
remark
:
'This is a sample approval process.'
,
businessKey
:
'BUS-12345'
,
createTime
:
'2024-11-01T09:00:00Z'
,
endTime
:
''
,
processDefinition
:
undefined
// Not populated in this example
};
// 模拟的 activityNodes 数据,传递给 ProcessInstanceTimeline 组件
const
activityNodes
:
ApprovalNodeInfo
[]
=
[
approvalNode1
,
approvalNode2
,
approvalNode3
];
export
{
processInstance
,
activityNodes
,
users
};
export
const
startUserSelectTasks
=
users
.
map
(
user
=>
({
id
:
user
.
id
,
name
:
user
.
nickname
}))
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
View file @
8b5740d0
...
...
@@ -38,11 +38,29 @@
</div>
<!-- 需要自定义选择审批人 -->
<div
v-if=
"startUserSelectTasks?.length > 0 && activity.nodeType === NodeType.USER_TASK_NODE"
class=
"flex flex-wrap gap2 items-center"
v-if=
"
startUserSelectTasks?.length > 0 && Array.isArray(startUserSelectAssignees[activity.id])
"
>
<!-- && activity.nodeType === NodeType.USER_TASK_NODE -->
<el-button
class=
"!px-8px"
@
click=
"handleSelectUser(activity.id, customApprover[activity.id])"
>
<el-button
class=
"!px-8px"
@
click=
"handleSelectUser"
>
<Icon
icon=
"fa:user-plus"
/>
</el-button>
<div
v-for=
"(user, idx1) in customApprover[activity.id]"
:key=
"idx1"
class=
"bg-gray-100 h-35px rounded-3xl flex items-center p-8px gap-2 dark:color-gray-600 position-relative"
>
<el-avatar
:size=
"28"
v-if=
"user.avatar"
:src=
"user.avatar"
/>
<el-avatar
:size=
"28"
v-else
>
{{ user.nickname.substring(0, 1) }}
</el-avatar>
{{ user.nickname }}
</div>
</div>
<div
v-else
class=
"flex items-center flex-wrap mt-1 gap2"
>
<!-- 情况一:遍历每个审批节点下的【进行中】task 任务 -->
...
...
@@ -152,10 +170,12 @@ withDefaults(
activityNodes
:
ProcessInstanceApi
.
ApprovalNodeInfo
[]
// 审批节点信息
showStatusIcon
?:
boolean
// 是否显示头像右下角状态图标
startUserSelectTasks
?:
any
[]
// 发起人需要选择审批人的用户任务列表
startUserSelectAssignees
?:
any
// 发起人选择审批人的数据
}
>
(),
{
showStatusIcon
:
true
,
// 默认值为 true
startUserSelectTasks
:
()
=>
[]
// 默认值为空数组
startUserSelectTasks
:
()
=>
[],
// 默认值为空数组
startUserSelectAssignees
:
()
=>
{}
}
)
...
...
@@ -256,11 +276,16 @@ const getApprovalNodeTime = (node: ProcessInstanceApi.ApprovalNodeInfo) => {
// 选择自定义审批人
const
userSelectFormRef
=
ref
()
const
handleSelectUser
=
()
=>
{
userSelectFormRef
.
value
.
open
()
const
handleSelectUser
=
(
activityId
,
selectedList
)
=>
{
userSelectFormRef
.
value
.
open
(
activityId
,
selectedList
)
}
const
emit
=
defineEmits
<
{
selectUserConfirm
:
[
id
:
any
,
userList
:
any
[]]
}
>
()
const
customApprover
:
any
=
ref
({})
// 选择完成
const
handleUserSelectConfirm
=
(
userList
)
=>
{
console
.
log
(
'[ userList ] >'
,
userList
)
const
handleUserSelectConfirm
=
(
activityId
,
userList
)
=>
{
customApprover
.
value
[
activityId
]
=
userList
||
[]
emit
(
'selectUserConfirm'
,
activityId
,
userList
)
}
</
script
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment