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
Unverified
Commit
32d00934
authored
Nov 07, 2024
by
芋道源码
Committed by
GitHub
Nov 07, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #99 from GoldenZqqq/feature/bpm
发起流程界面功能点优化与bug修复
parents
5121d569
6dd6f9c2
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
272 additions
and
88 deletions
+272
-88
src/components/UserSelectForm/index.vue
+100
-0
src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue
+18
-57
src/views/bpm/processInstance/create/index.vue
+101
-24
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
+53
-6
src/views/bpm/processInstance/index.vue
+0
-1
No files found.
src/components/UserSelectForm/index.vue
0 → 100644
View file @
32d00934
<
template
>
<Dialog
v-model=
"dialogVisible"
title=
"人员选择"
width=
"900"
>
<el-row>
<el-col
:span=
"6"
>
<el-tree
ref=
"treeRef"
:data=
"deptList"
:expand-on-click-node=
"false"
:props=
"defaultProps"
default-expand-all
highlight-current
node-key=
"id"
@
node-click=
"handleNodeClick"
/>
</el-col>
<el-col
:span=
"17"
:offset=
"1"
>
<el-transfer
v-model=
"selectedUserIdList"
filterable
filter-placeholder=
"搜索成员"
:data=
"userList"
:props=
"
{ label: 'nickname', key: 'id' }"
/>
</el-col>
</el-row>
<template
#
footer
>
<el-button
:disabled=
"formLoading || !selectedUserIdList?.length"
type=
"primary"
@
click=
"submitForm"
>
确 定
</el-button
>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
lang=
"ts"
setup
>
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
*
as
DeptApi
from
'@/api/system/dept'
import
*
as
UserApi
from
'@/api/system/user'
defineOptions
({
name
:
'UserSelectForm'
})
const
emit
=
defineEmits
<
{
confirm
:
[
id
:
any
,
userList
:
any
[]]
}
>
()
const
{
t
}
=
useI18n
()
// 国际
const
deptList
=
ref
<
Tree
[]
>
([])
// 部门树形结构化
const
userList
:
any
=
ref
([])
// 用户列表
const
message
=
useMessage
()
// 消息弹窗
const
selectedUserIdList
:
any
=
ref
([])
// 选中的用户列表
const
dialogVisible
=
ref
(
false
)
// 弹窗的是否展示
const
formLoading
=
ref
(
false
)
// 表单的加载中
const
activityId
=
ref
()
// 主键id
/** 打开弹窗 */
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
}
/* 获取用户列表 */
const
getUserList
=
async
(
deptId
?)
=>
{
try
{
// @ts-ignore
const
data
=
await
UserApi
.
getUserPage
({
pageSize
:
100
,
pageNo
:
1
,
deptId
})
userList
.
value
=
data
.
list
}
finally
{
}
}
const
submitForm
=
async
()
=>
{
// 提交请求
formLoading
.
value
=
true
try
{
message
.
success
(
t
(
'common.updateSuccess'
))
dialogVisible
.
value
=
false
const
emitUserList
=
userList
.
value
.
filter
((
user
)
=>
selectedUserIdList
.
value
.
includes
(
user
.
id
))
// 发送操作成功的事件
emit
(
'confirm'
,
activityId
.
value
,
emitUserList
)
}
finally
{
formLoading
.
value
=
false
}
}
const
resetForm
=
()
=>
{
deptList
.
value
=
[]
userList
.
value
=
[]
selectedUserIdList
.
value
=
[]
}
/** 处理部门被点击 */
const
handleNodeClick
=
async
(
row
:
{
[
key
:
string
]:
any
})
=>
{
getUserList
(
row
.
id
)
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
</
script
>
src/views/bpm/processInstance/create/ProcessDefinitionDetail.vue
View file @
32d00934
...
@@ -19,40 +19,7 @@
...
@@ -19,40 +19,7 @@
v-model=
"detailForm.value"
v-model=
"detailForm.value"
:option=
"detailForm.option"
:option=
"detailForm.option"
@
submit=
"submitForm"
@
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>
<el-col
:span=
"6"
:offset=
"1"
>
<el-col
:span=
"6"
:offset=
"1"
>
...
@@ -61,7 +28,9 @@
...
@@ -61,7 +28,9 @@
ref=
"timelineRef"
ref=
"timelineRef"
:activity-nodes=
"activityNodes"
:activity-nodes=
"activityNodes"
:show-status-icon=
"false"
:show-status-icon=
"false"
candidateField=
"candidateUserList"
:startUserSelectTasks=
"startUserSelectTasks"
:startUserSelectAssignees=
"startUserSelectAssignees"
@
select-user-confirm=
"selectUserConfirm"
/>
/>
</el-col>
</el-col>
</el-row>
</el-row>
...
@@ -104,7 +73,6 @@ import type { ApiAttrs } from '@form-create/element-ui/types/config'
...
@@ -104,7 +73,6 @@ import type { ApiAttrs } from '@form-create/element-ui/types/config'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
{
useTagsViewStore
}
from
'@/store/modules/tagsView'
import
*
as
ProcessInstanceApi
from
'@/api/bpm/processInstance'
import
*
as
ProcessInstanceApi
from
'@/api/bpm/processInstance'
import
*
as
DefinitionApi
from
'@/api/bpm/definition'
import
*
as
DefinitionApi
from
'@/api/bpm/definition'
import
*
as
UserApi
from
'@/api/system/user'
defineOptions
({
name
:
'ProcessDefinitionDetail'
})
defineOptions
({
name
:
'ProcessDefinitionDetail'
})
const
props
=
defineProps
<
{
const
props
=
defineProps
<
{
...
@@ -121,11 +89,8 @@ const detailForm: any = ref({
...
@@ -121,11 +89,8 @@ const detailForm: any = ref({
})
// 流程表单详情
})
// 流程表单详情
const
fApi
=
ref
<
ApiAttrs
>
()
const
fApi
=
ref
<
ApiAttrs
>
()
// 指定审批人
// 指定审批人
const
startUserSelectAssigneesFormRef
=
ref
()
// 发起人选择审批人的表单 Ref
const
startUserSelectTasks
:
any
=
ref
([])
// 发起人需要选择审批人的用户任务列表
const
startUserSelectTasks
:
any
=
ref
([])
// 发起人需要选择审批人的用户任务列表
const
startUserSelectAssignees
=
ref
({})
// 发起人选择审批人的数据
const
startUserSelectAssignees
=
ref
({})
// 发起人选择审批人的数据
const
startUserSelectAssigneesFormRules
=
ref
({})
// 发起人选择审批人的表单 Rules
const
userList
=
ref
<
any
[]
>
([])
// 用户列表
const
bpmnXML
:
any
=
ref
(
null
)
// BPMN 数据
const
bpmnXML
:
any
=
ref
(
null
)
// BPMN 数据
/** 当前的Tab */
/** 当前的Tab */
const
activeTab
=
ref
(
'form'
)
const
activeTab
=
ref
(
'form'
)
...
@@ -138,7 +103,6 @@ const initProcessInfo = async (row: any, formVariables?: any) => {
...
@@ -138,7 +103,6 @@ const initProcessInfo = async (row: any, formVariables?: any) => {
// 重置指定审批人
// 重置指定审批人
startUserSelectTasks
.
value
=
[]
startUserSelectTasks
.
value
=
[]
startUserSelectAssignees
.
value
=
{}
startUserSelectAssignees
.
value
=
{}
startUserSelectAssigneesFormRules
.
value
=
{}
// 情况一:流程表单
// 情况一:流程表单
if
(
row
.
formType
==
10
)
{
if
(
row
.
formType
==
10
)
{
...
@@ -163,24 +127,12 @@ const initProcessInfo = async (row: any, formVariables?: any) => {
...
@@ -163,24 +127,12 @@ const initProcessInfo = async (row: any, formVariables?: any) => {
if
(
processDefinitionDetail
)
{
if
(
processDefinitionDetail
)
{
bpmnXML
.
value
=
processDefinitionDetail
.
bpmnXml
bpmnXML
.
value
=
processDefinitionDetail
.
bpmnXml
startUserSelectTasks
.
value
=
processDefinitionDetail
.
startUserSelectTasks
startUserSelectTasks
.
value
=
processDefinitionDetail
.
startUserSelectTasks
// 设置指定审批人
// 设置指定审批人
if
(
startUserSelectTasks
.
value
?.
length
>
0
)
{
if
(
startUserSelectTasks
.
value
?.
length
>
0
)
{
detailForm
.
value
.
rule
.
push
({
type
:
'startUserSelect'
,
props
:
{
title
:
'指定审批人'
}
})
// 设置校验规则
for
(
const
userTask
of
startUserSelectTasks
.
value
)
{
for
(
const
userTask
of
startUserSelectTasks
.
value
)
{
// 初始化数据
startUserSelectAssignees
.
value
[
userTask
.
id
]
=
[]
startUserSelectAssignees
.
value
[
userTask
.
id
]
=
[]
startUserSelectAssigneesFormRules
.
value
[
userTask
.
id
]
=
[
{
required
:
true
,
message
:
'请选择审批人'
,
trigger
:
'blur'
}
]
}
}
// 加载用户列表
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
}
}
}
}
// 情况二:业务表单
// 情况二:业务表单
...
@@ -209,14 +161,19 @@ const getApprovalDetail = async (row: any) => {
...
@@ -209,14 +161,19 @@ const getApprovalDetail = async (row: any) => {
}
}
}
}
/** 提交按钮 */
/** 提交按钮 */
const
submitForm
=
async
(
formData
:
any
)
=>
{
const
submitForm
=
async
()
=>
{
debugger
if
(
!
fApi
.
value
||
!
props
.
selectProcessDefinition
)
{
if
(
!
fApi
.
value
||
!
props
.
selectProcessDefinition
)
{
return
return
}
}
// 如果有指定审批人,需要校验
// 如果有指定审批人,需要校验
if
(
startUserSelectTasks
.
value
?.
length
>
0
)
{
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
}
的审批人`
)
}
}
}
// 提交请求
// 提交请求
...
@@ -224,7 +181,7 @@ const submitForm = async (formData: any) => {
...
@@ -224,7 +181,7 @@ const submitForm = async (formData: any) => {
try
{
try
{
await
ProcessInstanceApi
.
createProcessInstance
({
await
ProcessInstanceApi
.
createProcessInstance
({
processDefinitionId
:
props
.
selectProcessDefinition
.
id
,
processDefinitionId
:
props
.
selectProcessDefinition
.
id
,
variables
:
formData
||
detailForm
.
value
.
value
,
variables
:
detailForm
.
value
.
value
,
startUserSelectAssignees
:
startUserSelectAssignees
.
value
startUserSelectAssignees
:
startUserSelectAssignees
.
value
})
})
// 提示
// 提示
...
@@ -243,6 +200,10 @@ const handleCancel = () => {
...
@@ -243,6 +200,10 @@ const handleCancel = () => {
emit
(
'cancel'
)
emit
(
'cancel'
)
}
}
const
selectUserConfirm
=
(
id
,
userList
)
=>
{
startUserSelectAssignees
.
value
[
id
]
=
userList
?.
map
((
item
)
=>
item
.
id
)
}
defineExpose
({
initProcessInfo
})
defineExpose
({
initProcessInfo
})
</
script
>
</
script
>
...
@@ -250,7 +211,7 @@ defineExpose({ initProcessInfo })
...
@@ -250,7 +211,7 @@ defineExpose({ initProcessInfo })
$
wrap-padding-height
:
20px
;
$
wrap-padding-height
:
20px
;
$
wrap-margin-height
:
15px
;
$
wrap-margin-height
:
15px
;
$
button-height
:
51px
;
$
button-height
:
51px
;
$
process-header-height
:
1
94
px
;
$
process-header-height
:
1
05
px
;
.processInstance-wrap-main
{
.processInstance-wrap-main
{
height
:
calc
(
height
:
calc
(
...
...
src/views/bpm/processInstance/create/index.vue
View file @
32d00934
<
template
>
<
template
>
<!-- 第一步,通过流程定义的列表,选择对应的流程 -->
<!-- 第一步,通过流程定义的列表,选择对应的流程 -->
<template
v-if=
"!selectProcessDefinition"
>
<el-input
v-model=
"currentSearchKey"
class=
"!w-50% mb-15px"
placeholder=
"请输入流程名称"
clearable
@
keyup
.
enter=
"handleQuery"
@
clear=
"handleClear"
>
<template
#
prefix
>
<Icon
icon=
"ep:search"
/>
</
template
>
</el-input>
<ContentWrap
<ContentWrap
class=
"process-definition-container position-relative pb-20px
"
:class=
"{ 'process-definition-container': filteredProcessDefinitionList?.length }
"
v-if=
"!selectProcessDefinition
"
class=
"position-relative pb-20px h-700px
"
v-loading=
"loading"
v-loading=
"loading"
>
>
<el-row
:gutter=
"20"
class=
"!flex-nowrap"
>
<el-row
v-if=
"filteredProcessDefinitionList?.length"
:gutter=
"20"
class=
"!flex-nowrap"
>
<el-col
:span=
"5"
>
<el-col
:span=
"5"
>
<div
class=
"flex flex-col"
>
<div
class=
"flex flex-col"
>
<div
<div
...
@@ -20,11 +33,22 @@
...
@@ -20,11 +33,22 @@
</div>
</div>
</el-col>
</el-col>
<el-col
:span=
"19"
>
<el-col
:span=
"19"
>
<h3
class=
"text-16px font-bold mb-10px mt-5px"
>
{{
categoryActive
.
name
}}
</h3>
<el-scrollbar
ref=
"scrollWrapper"
height=
"700"
>
<div
class=
"grid grid-cols-3 gap3"
v-if=
"categoryProcessDefinitionList.length"
>
<div
<el-card
class=
"mb-20px pl-10px"
v-for=
"definition in categoryProcessDefinitionList"
v-for=
"(definitions, title) in processDefinitionGroup"
:key=
"title"
:ref=
"`category-${title}`"
>
<h3
class=
"text-18px font-bold mb-10px mt-5px"
>
{{ title }}
</h3>
<div
class=
"grid grid-cols-3 gap3"
>
<el-tooltip
v-for=
"definition in definitions"
:key=
"definition.id"
:key=
"definition.id"
:content=
"definition.description"
placement=
"top"
>
<el-card
shadow=
"hover"
shadow=
"hover"
class=
"cursor-pointer definition-item-card"
class=
"cursor-pointer definition-item-card"
@
click=
"handleSelect(definition)"
@
click=
"handleSelect(definition)"
...
@@ -36,11 +60,15 @@
...
@@ -36,11 +60,15 @@
</div>
</div>
</
template
>
</
template
>
</el-card>
</el-card>
</el-tooltip>
</div>
</div>
</div>
<el-empty
v-else
/
>
</el-scrollbar
>
</el-col>
</el-col>
</el-row>
</el-row>
<el-empty
class=
"!py-200px"
:image-size=
"200"
description=
"没有找到搜索结果"
v-else
/>
</ContentWrap>
</ContentWrap>
</template>
<!-- 第二步,填写表单,进行流程的提交 -->
<!-- 第二步,填写表单,进行流程的提交 -->
<ProcessDefinitionDetail
<ProcessDefinitionDetail
...
@@ -56,12 +84,14 @@ import * as DefinitionApi from '@/api/bpm/definition'
...
@@ -56,12 +84,14 @@ import * as DefinitionApi from '@/api/bpm/definition'
import
*
as
ProcessInstanceApi
from
'@/api/bpm/processInstance'
import
*
as
ProcessInstanceApi
from
'@/api/bpm/processInstance'
import
{
CategoryApi
}
from
'@/api/bpm/category'
import
{
CategoryApi
}
from
'@/api/bpm/category'
import
ProcessDefinitionDetail
from
'./ProcessDefinitionDetail.vue'
import
ProcessDefinitionDetail
from
'./ProcessDefinitionDetail.vue'
import
{
groupBy
}
from
'lodash-es'
defineOptions
({
name
:
'BpmProcessInstanceCreate'
})
defineOptions
({
name
:
'BpmProcessInstanceCreate'
})
const
{
proxy
}
=
getCurrentInstance
()
as
any
const
route
=
useRoute
()
// 路由
const
route
=
useRoute
()
// 路由
const
message
=
useMessage
()
// 消息
const
message
=
useMessage
()
// 消息
const
currentSearchKey
=
ref
(
''
)
// 当前搜索关键字
const
processInstanceId
:
any
=
route
.
query
.
processInstanceId
const
processInstanceId
:
any
=
route
.
query
.
processInstanceId
const
loading
=
ref
(
true
)
// 加载中
const
loading
=
ref
(
true
)
// 加载中
const
categoryList
:
any
=
ref
([])
// 分类的列表
const
categoryList
:
any
=
ref
([])
// 分类的列表
...
@@ -71,15 +101,10 @@ const processDefinitionList = ref([]) // 流程定义的列表
...
@@ -71,15 +101,10 @@ const processDefinitionList = ref([]) // 流程定义的列表
const
getList
=
async
()
=>
{
const
getList
=
async
()
=>
{
loading
.
value
=
true
loading
.
value
=
true
try
{
try
{
// 流程分类
// 所有流程分类数据
categoryList
.
value
=
await
CategoryApi
.
getCategorySimpleList
()
await
getCategoryList
()
if
(
categoryList
.
value
.
length
>
0
)
{
// 所有流程定义数据
categoryActive
.
value
=
categoryList
.
value
[
0
]
await
getDefinitionList
()
}
// 流程定义
processDefinitionList
.
value
=
await
DefinitionApi
.
getProcessDefinitionList
({
suspensionState
:
1
})
// 如果 processInstanceId 非空,说明是重新发起
// 如果 processInstanceId 非空,说明是重新发起
if
(
processInstanceId
?.
length
>
0
)
{
if
(
processInstanceId
?.
length
>
0
)
{
...
@@ -102,11 +127,55 @@ const getList = async () => {
...
@@ -102,11 +127,55 @@ const getList = async () => {
}
}
}
}
/** 选中分类对应的流程定义列表 */
// 获取所有流程分类数据
const
categoryProcessDefinitionList
:
any
=
computed
(()
=>
{
const
getCategoryList
=
async
()
=>
{
return
processDefinitionList
.
value
.
filter
(
try
{
(
item
:
any
)
=>
item
.
category
==
categoryActive
.
value
.
code
// 流程分类
categoryList
.
value
=
await
CategoryApi
.
getCategorySimpleList
()
if
(
categoryList
.
value
.
length
>
0
)
{
categoryActive
.
value
=
categoryList
.
value
[
0
]
}
}
finally
{
}
}
// 获取所有流程定义数据
const
getDefinitionList
=
async
()
=>
{
try
{
// 流程定义
processDefinitionList
.
value
=
await
DefinitionApi
.
getProcessDefinitionList
({
suspensionState
:
1
})
// 初始化过滤列表为全部流程定义
filteredProcessDefinitionList
.
value
=
processDefinitionList
.
value
}
finally
{
}
}
const
filteredProcessDefinitionList
=
ref
([])
// 用于存储搜索过滤后的流程定义
// 直接进行前端搜索
const
handleQuery
=
()
=>
{
if
(
currentSearchKey
.
value
.
trim
())
{
// 如果有搜索关键字,进行过滤
filteredProcessDefinitionList
.
value
=
processDefinitionList
.
value
.
filter
(
(
definition
:
any
)
=>
definition
.
name
.
toLowerCase
().
includes
(
currentSearchKey
.
value
.
toLowerCase
())
// 假设搜索依据是流程定义的名称
)
)
}
else
{
// 如果没有搜索关键字,恢复所有数据
filteredProcessDefinitionList
.
value
=
processDefinitionList
.
value
}
}
// 监听input `clearable` 事件
const
handleClear
=
()
=>
{
filteredProcessDefinitionList
.
value
=
processDefinitionList
.
value
}
// 流程定义的分组
const
processDefinitionGroup
:
any
=
computed
(()
=>
{
if
(
!
processDefinitionList
.
value
?.
length
)
return
{}
return
groupBy
(
filteredProcessDefinitionList
.
value
,
'categoryName'
)
})
})
// ========== 表单相关 ==========
// ========== 表单相关 ==========
...
@@ -122,8 +191,16 @@ const handleSelect = async (row, formVariables?) => {
...
@@ -122,8 +191,16 @@ const handleSelect = async (row, formVariables?) => {
processDefinitionDetailRef
.
value
?.
initProcessInfo
(
row
,
formVariables
)
processDefinitionDetailRef
.
value
?.
initProcessInfo
(
row
,
formVariables
)
}
}
// 左侧分类切换
// 左侧分类切换
const
handleCategoryClick
=
(
val
:
number
)
=>
{
const
handleCategoryClick
=
(
category
)
=>
{
categoryActive
.
value
=
val
categoryActive
.
value
=
category
const
categoryRef
=
proxy
.
$refs
[
`category-
${
category
.
name
}
`
]
// 获取点击分类对应的 DOM 元素
if
(
categoryRef
?.
length
)
{
const
scrollWrapper
=
proxy
.
$refs
.
scrollWrapper
// 获取右侧滚动容器
const
categoryOffsetTop
=
categoryRef
[
0
].
offsetTop
// 滚动到对应位置
scrollWrapper
.
scrollTo
({
top
:
categoryOffsetTop
,
behavior
:
'smooth'
})
}
}
}
/** 初始化 */
/** 初始化 */
...
...
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
View file @
32d00934
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
</div>
</div>
</div>
</div>
</
template
>
</
template
>
<div
class=
"flex flex-col items-start"
>
<div
class=
"flex flex-col items-start
gap2"
:id=
"`activity-task-${activity.id}`
"
>
<!-- 第一行:节点名称、时间 -->
<!-- 第一行:节点名称、时间 -->
<div
class=
"flex w-full"
>
<div
class=
"flex w-full"
>
<div
class=
"font-bold"
>
{{ activity.name }}
</div>
<div
class=
"font-bold"
>
{{ activity.name }}
</div>
...
@@ -36,10 +36,35 @@
...
@@ -36,10 +36,35 @@
{{ getApprovalNodeTime(activity) }}
{{ getApprovalNodeTime(activity) }}
</div>
</div>
</div>
</div>
<div
class=
"flex items-center flex-wrap mt-1"
>
<!-- 需要自定义选择审批人 -->
<div
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])"
>
<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 任务 -->
<!-- 情况一:遍历每个审批节点下的【进行中】task 任务 -->
<div
v-for=
"(task, idx) in activity.tasks"
:key=
"idx"
class=
"flex items-center"
>
<div
v-for=
"(task, idx) in activity.tasks"
:key=
"idx"
class=
"flex flex-col pr-2 gap2"
>
<div
class=
"flex flex-col pr-2 gap2"
>
<div
<div
class=
"position-relative flex flex-wrap gap2"
class=
"position-relative flex flex-wrap gap2"
v-if=
"task.assigneeUser || task.ownerUser"
v-if=
"task.assigneeUser || task.ownerUser"
...
@@ -83,6 +108,7 @@
...
@@ -83,6 +108,7 @@
</div>
</div>
</div>
</div>
</div>
</div>
<teleport
defer
:to=
"`#activity-task-${activity.id}`"
>
<div
<div
v-if=
"
v-if=
"
task.reason &&
task.reason &&
...
@@ -92,7 +118,7 @@
...
@@ -92,7 +118,7 @@
>
>
审批意见:{{ task.reason }}
审批意见:{{ task.reason }}
</div>
</div>
</
div
>
</
teleport
>
</div>
</div>
<!-- 情况二:遍历每个审批节点下的【候选的】task 任务。例如说,1)依次审批,2)未来的审批任务等 -->
<!-- 情况二:遍历每个审批节点下的【候选的】task 任务。例如说,1)依次审批,2)未来的审批任务等 -->
<div
<div
...
@@ -121,6 +147,8 @@
...
@@ -121,6 +147,8 @@
</div>
</div>
</el-timeline-item>
</el-timeline-item>
</el-timeline>
</el-timeline>
<!-- 用户选择弹窗 -->
<UserSelectForm
ref=
"userSelectFormRef"
@
confirm=
"handleUserSelectConfirm"
/>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
...
@@ -141,9 +169,13 @@ withDefaults(
...
@@ -141,9 +169,13 @@ withDefaults(
defineProps
<
{
defineProps
<
{
activityNodes
:
ProcessInstanceApi
.
ApprovalNodeInfo
[]
// 审批节点信息
activityNodes
:
ProcessInstanceApi
.
ApprovalNodeInfo
[]
// 审批节点信息
showStatusIcon
?:
boolean
// 是否显示头像右下角状态图标
showStatusIcon
?:
boolean
// 是否显示头像右下角状态图标
startUserSelectTasks
?:
any
[]
// 发起人需要选择审批人的用户任务列表
startUserSelectAssignees
?:
any
// 发起人选择审批人的数据
}
>
(),
}
>
(),
{
{
showStatusIcon
:
true
// 默认值为 true
showStatusIcon
:
true
,
// 默认值为 true
startUserSelectTasks
:
()
=>
[],
// 默认值为空数组
startUserSelectAssignees
:
()
=>
{}
}
}
)
)
...
@@ -241,4 +273,19 @@ const getApprovalNodeTime = (node: ProcessInstanceApi.ApprovalNodeInfo) => {
...
@@ -241,4 +273,19 @@ const getApprovalNodeTime = (node: ProcessInstanceApi.ApprovalNodeInfo) => {
return
`
${
formatDate
(
node
.
startTime
)}
`
return
`
${
formatDate
(
node
.
startTime
)}
`
}
}
}
}
// 选择自定义审批人
const
userSelectFormRef
=
ref
()
const
handleSelectUser
=
(
activityId
,
selectedList
)
=>
{
userSelectFormRef
.
value
.
open
(
activityId
,
selectedList
)
}
const
emit
=
defineEmits
<
{
selectUserConfirm
:
[
id
:
any
,
userList
:
any
[]]
}
>
()
const
customApprover
:
any
=
ref
({})
// 选择完成
const
handleUserSelectConfirm
=
(
activityId
,
userList
)
=>
{
customApprover
.
value
[
activityId
]
=
userList
||
[]
emit
(
'selectUserConfirm'
,
activityId
,
userList
)
}
</
script
>
</
script
>
src/views/bpm/processInstance/index.vue
View file @
32d00934
...
@@ -222,7 +222,6 @@ const handleCreate = async (row?: ProcessInstanceVO) => {
...
@@ -222,7 +222,6 @@ const handleCreate = async (row?: ProcessInstanceVO) => {
const
processDefinitionDetail
=
await
DefinitionApi
.
getProcessDefinition
(
const
processDefinitionDetail
=
await
DefinitionApi
.
getProcessDefinition
(
row
.
processDefinitionId
row
.
processDefinitionId
)
)
debugger
if
(
processDefinitionDetail
.
formType
===
20
)
{
if
(
processDefinitionDetail
.
formType
===
20
)
{
message
.
error
(
'重新发起流程失败,原因:该流程使用业务表单,不支持重新发起'
)
message
.
error
(
'重新发起流程失败,原因:该流程使用业务表单,不支持重新发起'
)
return
return
...
...
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