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
575f6038
authored
Feb 12, 2025
by
芋道源码
Committed by
Gitee
Feb 12, 2025
Browse files
Options
Browse Files
Download
Plain Diff
!692 BPM设计器-办理人节点
Merge pull request !692 from Lesan/feature/bpm-办理人
parents
b0d4e39e
a190a0b4
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
169 additions
and
110 deletions
+169
-110
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
+9
-3
src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue
+5
-1
src/components/SimpleProcessDesignerV2/src/consts.ts
+17
-0
src/components/SimpleProcessDesignerV2/src/node.ts
+1
-1
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
+131
-103
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
+1
-1
src/views/bpm/processInstance/detail/ProcessInstanceSimpleViewer.vue
+2
-1
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
+3
-0
No files found.
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
View file @
575f6038
...
...
@@ -15,6 +15,12 @@
</div>
<div
class=
"handler-item-text"
>
审批人
</div>
</div>
<div
class=
"handler-item"
@
click=
"addNode(NodeType.TRANSACTOR_NODE)"
>
<div
class=
"approve handler-item-icon"
>
<span
class=
"iconfont icon-approve icon-size"
></span>
</div>
<div
class=
"handler-item-text"
>
办理人
</div>
</div>
<div
class=
"handler-item"
@
click=
"addNode(NodeType.COPY_TASK_NODE)"
>
<div
class=
"handler-item-icon copy"
>
<span
class=
"iconfont icon-size icon-copy"
></span>
...
...
@@ -114,13 +120,13 @@ const addNode = (type: number) => {
}
popoverShow
.
value
=
false
if
(
type
===
NodeType
.
USER_TASK_NODE
)
{
if
(
type
===
NodeType
.
USER_TASK_NODE
||
type
===
NodeType
.
TRANSACTOR_NODE
)
{
const
id
=
'Activity_'
+
generateUUID
()
const
data
:
SimpleFlowNode
=
{
id
:
id
,
name
:
NODE_DEFAULT_NAME
.
get
(
NodeType
.
USER_TASK_NODE
)
as
string
,
name
:
NODE_DEFAULT_NAME
.
get
(
type
)
as
string
,
showText
:
''
,
type
:
NodeType
.
USER_TASK_NODE
,
type
:
type
,
approveMethod
:
ApproveMethodType
.
SEQUENTIAL_APPROVE
,
// 超时处理
rejectHandler
:
{
...
...
src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue
View file @
575f6038
...
...
@@ -6,7 +6,11 @@
/>
<!-- 审批节点 -->
<UserTaskNode
v-if=
"currentNode && currentNode.type === NodeType.USER_TASK_NODE"
v-if=
"
currentNode &&
(currentNode.type === NodeType.USER_TASK_NODE ||
currentNode.type === NodeType.TRANSACTOR_NODE)
"
:flow-node=
"currentNode"
@
update:flow-node=
"handleModelValueUpdate"
@
find:parent-node=
"findFromParentNode"
...
...
src/components/SimpleProcessDesignerV2/src/consts.ts
View file @
575f6038
...
...
@@ -24,6 +24,11 @@ export enum NodeType {
COPY_TASK_NODE
=
12
,
/**
* 办理人节点
*/
TRANSACTOR_NODE
=
13
,
/**
* 延迟器节点
*/
DELAY_TIMER_NODE
=
14
,
...
...
@@ -506,6 +511,7 @@ NODE_DEFAULT_TEXT.set(NodeType.START_USER_NODE, '请设置发起人')
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
DELAY_TIMER_NODE
,
'请设置延迟器'
)
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
ROUTER_BRANCH_NODE
,
'请设置路由节点'
)
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
TRIGGER_NODE
,
'请设置触发器'
)
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
TRANSACTOR_NODE
,
'请设置办理人'
)
export
const
NODE_DEFAULT_NAME
=
new
Map
<
number
,
string
>
()
NODE_DEFAULT_NAME
.
set
(
NodeType
.
USER_TASK_NODE
,
'审批人'
)
...
...
@@ -515,6 +521,7 @@ NODE_DEFAULT_NAME.set(NodeType.START_USER_NODE, '发起人')
NODE_DEFAULT_NAME
.
set
(
NodeType
.
DELAY_TIMER_NODE
,
'延迟器'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
ROUTER_BRANCH_NODE
,
'路由分支'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
TRIGGER_NODE
,
'触发器'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
TRANSACTOR_NODE
,
'办理人'
)
// 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序
export
const
CANDIDATE_STRATEGY
:
DictDataVO
[]
=
[
...
...
@@ -627,6 +634,16 @@ export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [
{
id
:
OperationButtonType
.
RETURN
,
displayName
:
'退回'
,
enable
:
true
}
]
// 办理人默认的按钮权限设置
export
const
TRANSACTOR_DEFAULT_BUTTON_SETTING
:
ButtonSetting
[]
=
[
{
id
:
OperationButtonType
.
APPROVE
,
displayName
:
'办理'
,
enable
:
true
},
{
id
:
OperationButtonType
.
REJECT
,
displayName
:
'拒绝'
,
enable
:
false
},
{
id
:
OperationButtonType
.
TRANSFER
,
displayName
:
'转办'
,
enable
:
false
},
{
id
:
OperationButtonType
.
DELEGATE
,
displayName
:
'委派'
,
enable
:
false
},
{
id
:
OperationButtonType
.
ADD_SIGN
,
displayName
:
'加签'
,
enable
:
false
},
{
id
:
OperationButtonType
.
RETURN
,
displayName
:
'退回'
,
enable
:
false
}
]
// 发起人的按钮权限。暂时定死,不可以编辑
export
const
START_USER_BUTTON_SETTING
:
ButtonSetting
[]
=
[
{
id
:
OperationButtonType
.
APPROVE
,
displayName
:
'提交'
,
enable
:
true
},
...
...
src/components/SimpleProcessDesignerV2/src/node.ts
View file @
575f6038
...
...
@@ -201,7 +201,7 @@ export function useNodeForm(nodeType: NodeType) {
const
deptTreeOptions
=
inject
(
'deptTree'
,
ref
())
// 部门树
const
formFields
=
inject
<
Ref
<
string
[]
>>
(
'formFields'
,
ref
([]))
// 流程表单字段
const
configForm
=
ref
<
UserTaskFormType
|
CopyTaskFormType
>
()
if
(
nodeType
===
NodeType
.
USER_TASK_NODE
)
{
if
(
nodeType
===
NodeType
.
USER_TASK_NODE
||
nodeType
===
NodeType
.
TRANSACTOR_NODE
)
{
configForm
.
value
=
{
candidateStrategy
:
CandidateStrategy
.
USER
,
approveMethod
:
ApproveMethodType
.
SEQUENTIAL_APPROVE
,
...
...
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
View file @
575f6038
...
...
@@ -25,7 +25,7 @@
<div
class=
"divide-line"
></div>
</div>
</
template
>
<div
class=
"flex flex-items-center mb-3"
>
<div
v-if=
"currentNode.type === NodeType.USER_TASK_NODE"
class=
"flex flex-items-center mb-3"
>
<span
class=
"font-size-16px mr-3"
>
审批类型 :
</span>
<el-radio-group
v-model=
"approveType"
>
<el-radio
...
...
@@ -230,91 +230,100 @@
</el-radio-group>
</el-form-item>
<el-divider
content-position=
"left"
>
审批人拒绝时
</el-divider>
<el-form-item
prop=
"rejectHandlerType"
>
<el-radio-group
v-model=
"configForm.rejectHandlerType"
>
<div
class=
"flex-col"
>
<div
v-for=
"(item, index) in REJECT_HANDLER_TYPES"
:key=
"index"
>
<el-radio
:key=
"item.value"
:value=
"item.value"
:label=
"item.label"
/>
<div
v-if=
"currentNode.type === NodeType.USER_TASK_NODE"
>
<el-divider
content-position=
"left"
>
审批人拒绝时
</el-divider>
<el-form-item
prop=
"rejectHandlerType"
>
<el-radio-group
v-model=
"configForm.rejectHandlerType"
>
<div
class=
"flex-col"
>
<div
v-for=
"(item, index) in REJECT_HANDLER_TYPES"
:key=
"index"
>
<el-radio
:key=
"item.value"
:value=
"item.value"
:label=
"item.label"
/>
</div>
</div>
</div>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"configForm.rejectHandlerType == RejectHandlerType.RETURN_USER_TASK"
label=
"驳回节点"
prop=
"returnNodeId"
>
<el-select
filterable
v-model=
"configForm.returnNodeId"
clearable
style=
"width: 100%"
>
<el-option
v-for=
"item in returnTaskList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-form-item>
<el-divider
content-position=
"left"
>
审批人超时未处理时
</el-divider>
<el-form-item
label=
"启用开关"
prop=
"timeoutHandlerEnable"
>
<el-switch
v-model=
"configForm.timeoutHandlerEnable"
active-text=
"开启"
inactive-text=
"关闭"
@
change=
"timeoutHandlerChange"
/>
</el-form-item>
<el-form-item
label=
"执行动作"
prop=
"timeoutHandlerType"
v-if=
"configForm.timeoutHandlerEnable"
>
<el-radio-group
v-model=
"configForm.timeoutHandlerType"
@
change=
"timeoutHandlerTypeChanged"
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"configForm.rejectHandlerType == RejectHandlerType.RETURN_USER_TASK"
label=
"驳回节点"
prop=
"returnNodeId"
>
<el-radio-button
v-for=
"item in TIMEOUT_HANDLER_TYPES"
:key=
"item.value"
:value=
"item.value"
:label=
"item.label"
<el-select
filterable
v-model=
"configForm.returnNodeId"
clearable
style=
"width: 100%"
>
<el-option
v-for=
"item in returnTaskList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</el-form-item>
</div>
<div
v-if=
"currentNode.type === NodeType.USER_TASK_NODE"
>
<el-divider
content-position=
"left"
>
审批人超时未处理时
</el-divider>
<el-form-item
label=
"启用开关"
prop=
"timeoutHandlerEnable"
>
<el-switch
v-model=
"configForm.timeoutHandlerEnable"
active-text=
"开启"
inactive-text=
"关闭"
@
change=
"timeoutHandlerChange"
/>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"超时时间设置"
v-if=
"configForm.timeoutHandlerEnable"
>
<span
class=
"mr-2"
>
当超过
</span>
<el-form-item
prop=
"timeDuration"
>
<el-input-number
</el-form-item>
<el-form-item
label=
"执行动作"
prop=
"timeoutHandlerType"
v-if=
"configForm.timeoutHandlerEnable"
>
<el-radio-group
v-model=
"configForm.timeoutHandlerType"
@
change=
"timeoutHandlerTypeChanged"
>
<el-radio-button
v-for=
"item in TIMEOUT_HANDLER_TYPES"
:key=
"item.value"
:value=
"item.value"
:label=
"item.label"
/>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"超时时间设置"
v-if=
"configForm.timeoutHandlerEnable"
>
<span
class=
"mr-2"
>
当超过
</span>
<el-form-item
prop=
"timeDuration"
>
<el-input-number
class=
"mr-2"
:style=
"{ width: '100px' }"
v-model=
"configForm.timeDuration"
:min=
"1"
controls-position=
"right"
/>
</el-form-item>
<el-select
filterable
v-model=
"timeUnit"
class=
"mr-2"
:style=
"{ width: '100px' }"
v-model=
"configForm.timeDuration"
:min=
"1"
controls-position=
"right"
/>
@
change=
"timeUnitChange"
>
<el-option
v-for=
"item in TIME_UNIT_TYPES"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
未处理
</el-form-item>
<el-select
filterable
v-model=
"timeUnit"
class=
"mr-2"
:style=
"{ width: '100px' }"
@
change=
"timeUnitChange"
<el-form-item
label=
"最大提醒次数"
prop=
"maxRemindCount"
v-if=
"configForm.timeoutHandlerEnable && configForm.timeoutHandlerType === 1"
>
<el-option
v-for=
"item in TIME_UNIT_TYPES"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
未处理
</el-form-item>
<el-form-item
label=
"最大提醒次数"
prop=
"maxRemindCount"
v-if=
"configForm.timeoutHandlerEnable && configForm.timeoutHandlerType === 1"
>
<el-input-number
v-model=
"configForm.maxRemindCount"
:min=
"1"
:max=
"10"
/>
</el-form-item>
<el-input-number
v-model=
"configForm.maxRemindCount"
:min=
"1"
:max=
"10"
/>
</el-form-item>
</div>
<el-divider
content-position=
"left"
>
审批人为空时
</el-divider>
<el-form-item
prop=
"assignEmptyHandlerType"
>
...
...
@@ -348,30 +357,44 @@
</el-select>
</el-form-item>
<el-divider
content-position=
"left"
>
审批人与提交人为同一人时
</el-divider>
<el-form-item
prop=
"assignStartUserHandlerType"
>
<el-radio-group
v-model=
"configForm.assignStartUserHandlerType"
>
<div
class=
"flex-col"
>
<div
v-for=
"(item, index) in ASSIGN_START_USER_HANDLER_TYPES"
:key=
"index"
>
<el-radio
:key=
"item.value"
:value=
"item.value"
:label=
"item.label"
/>
<div
v-if=
"currentNode.type === NodeType.USER_TASK_NODE"
>
<el-divider
content-position=
"left"
>
审批人与提交人为同一人时
</el-divider>
<el-form-item
prop=
"assignStartUserHandlerType"
>
<el-radio-group
v-model=
"configForm.assignStartUserHandlerType"
>
<div
class=
"flex-col"
>
<div
v-for=
"(item, index) in ASSIGN_START_USER_HANDLER_TYPES"
:key=
"index"
>
<el-radio
:key=
"item.value"
:value=
"item.value"
:label=
"item.label"
/>
</div>
</div>
</
div
>
</el-
radio-group
>
</
el-form-item
>
</
el-radio-group
>
</el-
form-item
>
</
div
>
<el-divider
content-position=
"left"
>
是否需要签名
</el-divider>
<el-form-item
prop=
"signEnable"
>
<el-switch
v-model=
"configForm.signEnable"
active-text=
"是"
inactive-text=
"否"
/>
</el-form-item>
<div
v-if=
"currentNode.type === NodeType.USER_TASK_NODE"
>
<el-divider
content-position=
"left"
>
是否需要签名
</el-divider>
<el-form-item
prop=
"signEnable"
>
<el-switch
v-model=
"configForm.signEnable"
active-text=
"是"
inactive-text=
"否"
/>
</el-form-item>
</div>
<el-divider
content-position=
"left"
>
审批意见
</el-divider>
<el-form-item
prop=
"reasonRequire"
>
<el-switch
v-model=
"configForm.reasonRequire"
active-text=
"必填"
inactive-text=
"非必填"
/>
</el-form-item>
<div
v-if=
"currentNode.type === NodeType.USER_TASK_NODE"
>
<el-divider
content-position=
"left"
>
审批意见
</el-divider>
<el-form-item
prop=
"reasonRequire"
>
<el-switch
v-model=
"configForm.reasonRequire"
active-text=
"必填"
inactive-text=
"非必填"
/>
</el-form-item>
</div>
</el-form>
</div>
</el-tab-pane>
<el-tab-pane
label=
"操作按钮设置"
name=
"buttons"
>
<el-tab-pane
label=
"操作按钮设置"
v-if=
"currentNode.type === NodeType.USER_TASK_NODE"
name=
"buttons"
>
<div
class=
"button-setting-pane"
>
<div
class=
"button-setting-desc"
>
操作按钮
</div>
<div
class=
"button-setting-title"
>
...
...
@@ -485,7 +508,8 @@ import {
ASSIGN_EMPTY_HANDLER_TYPES
,
AssignEmptyHandlerType
,
FieldPermissionType
,
ProcessVariableEnum
ProcessVariableEnum
,
TRANSACTOR_DEFAULT_BUTTON_SETTING
}
from
'../consts'
import
{
...
...
@@ -588,7 +612,7 @@ const {
handleCandidateParam
,
parseCandidateParam
,
getShowText
}
=
useNodeForm
(
NodeType
.
USER_TASK_NODE
)
}
=
useNodeForm
(
currentNode
.
value
.
type
)
const
configForm
=
tempConfigForm
as
Ref
<
UserTaskFormType
>
// 改变审批人设置策略
...
...
@@ -733,13 +757,13 @@ const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
configForm
.
value
.
approveRatio
=
node
.
approveRatio
!
}
// 2.3 设置审批拒绝处理
configForm
.
value
.
rejectHandlerType
=
node
.
rejectHandler
!
.
type
configForm
.
value
.
rejectHandlerType
=
node
.
rejectHandler
?
.
type
configForm
.
value
.
returnNodeId
=
node
.
rejectHandler
?.
returnNodeId
const
matchNodeList
=
[]
emits
(
'find:returnTaskNodes'
,
matchNodeList
)
returnTaskList
.
value
=
matchNodeList
// 2.4 设置审批超时处理
configForm
.
value
.
timeoutHandlerEnable
=
node
.
timeoutHandler
!
.
enable
configForm
.
value
.
timeoutHandlerEnable
=
node
.
timeoutHandler
?
.
enable
if
(
node
.
timeoutHandler
?.
enable
&&
node
.
timeoutHandler
?.
timeDuration
)
{
const
strTimeDuration
=
node
.
timeoutHandler
.
timeDuration
let
parseTime
=
strTimeDuration
.
slice
(
2
,
strTimeDuration
.
length
-
1
)
...
...
@@ -755,7 +779,11 @@ const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
// 2.6 设置用户任务的审批人与发起人相同时
configForm
.
value
.
assignStartUserHandlerType
=
node
.
assignStartUserHandlerType
// 3. 操作按钮设置
buttonsSetting
.
value
=
cloneDeep
(
node
.
buttonsSetting
)
||
DEFAULT_BUTTON_SETTING
buttonsSetting
.
value
=
cloneDeep
(
node
.
buttonsSetting
)
||
(
node
.
type
===
NodeType
.
TRANSACTOR_NODE
?
TRANSACTOR_DEFAULT_BUTTON_SETTING
:
DEFAULT_BUTTON_SETTING
)
// 4. 表单字段权限配置
getNodeConfigFormFields
(
node
.
fieldsPermission
)
// 5. 监听器
...
...
@@ -773,7 +801,7 @@ const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
header
:
node
.
taskAssignListener
?.
header
??
[],
body
:
node
.
taskAssignListener
?.
body
??
[]
}
// 5.3 完成任务
// 5.3 完成任务
configForm
.
value
.
taskCompleteListenerEnable
=
node
.
taskCompleteListener
?.
enable
configForm
.
value
.
taskCompleteListenerPath
=
node
.
taskCompleteListener
?.
path
configForm
.
value
.
taskCompleteListener
=
{
...
...
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
View file @
575f6038
...
...
@@ -28,7 +28,7 @@
{{
currentNode
.
showText
}}
</div>
<div
class=
"node-text"
v-else
>
{{
NODE_DEFAULT_TEXT
.
get
(
NodeType
.
USER_TASK_NODE
)
}}
{{
NODE_DEFAULT_TEXT
.
get
(
currentNode
.
type
)
}}
</div>
<Icon
icon=
"ep:arrow-right-bold"
v-if=
"!readonly"
/>
</div>
...
...
src/views/bpm/processInstance/detail/ProcessInstanceSimpleViewer.vue
View file @
575f6038
...
...
@@ -84,7 +84,8 @@ const setSimpleModelNodeTaskStatus = (
// 审批节点
if
(
simpleModel
.
type
===
NodeType
.
START_USER_NODE
||
simpleModel
.
type
===
NodeType
.
USER_TASK_NODE
simpleModel
.
type
===
NodeType
.
USER_TASK_NODE
||
simpleModel
.
type
===
NodeType
.
TRANSACTOR_NODE
)
{
simpleModel
.
activityStatus
=
TaskStatusEnum
.
NOT_START
if
(
rejectedTaskActivityIds
.
includes
(
simpleModel
.
id
))
{
...
...
src/views/bpm/processInstance/detail/ProcessInstanceTimeline.vue
View file @
575f6038
...
...
@@ -240,6 +240,8 @@ const nodeTypeSvgMap = {
[
NodeType
.
START_USER_NODE
]:
{
color
:
'#909398'
,
svg
:
starterSvg
},
// 审批人节点
[
NodeType
.
USER_TASK_NODE
]:
{
color
:
'#ff943e'
,
svg
:
auditorSvg
},
// 办理人节点
[
NodeType
.
TRANSACTOR_NODE
]:
{
color
:
'#ff943e'
,
svg
:
auditorSvg
},
// 抄送人节点
[
NodeType
.
COPY_TASK_NODE
]:
{
color
:
'#3296fb'
,
svg
:
copySvg
},
// 条件分支节点
...
...
@@ -264,6 +266,7 @@ const getApprovalNodeIcon = (taskStatus: number, nodeType: NodeType) => {
if
(
nodeType
===
NodeType
.
START_USER_NODE
||
nodeType
===
NodeType
.
USER_TASK_NODE
||
nodeType
===
NodeType
.
TRANSACTOR_NODE
||
nodeType
===
NodeType
.
END_EVENT_NODE
)
{
return
statusIconMap
[
taskStatus
]?.
icon
...
...
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