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
ab9ce936
authored
Aug 17, 2024
by
jason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
仿钉钉流程设计器- 删除第1版,新增连续多级部分负责人策略
parent
fd13eb7f
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
287 additions
and
3339 deletions
+287
-3339
src/components/SimpleProcessDesigner/src/addNode.vue
+0
-386
src/components/SimpleProcessDesigner/src/consts.ts
+0
-64
src/components/SimpleProcessDesigner/src/drawer/approverDrawer.vue
+0
-434
src/components/SimpleProcessDesigner/src/drawer/copyerDrawer.vue
+0
-250
src/components/SimpleProcessDesigner/src/nodeWrap.vue
+0
-504
src/components/SimpleProcessDesigner/src/util.ts
+0
-218
src/components/SimpleProcessDesigner/theme/iconfont.ttf
+0
-0
src/components/SimpleProcessDesigner/theme/iconfont.woff
+0
-0
src/components/SimpleProcessDesigner/theme/iconfont.woff2
+0
-0
src/components/SimpleProcessDesigner/theme/workflow.css
+0
-1366
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
+2
-2
src/components/SimpleProcessDesignerV2/src/consts.ts
+47
-1
src/components/SimpleProcessDesignerV2/src/node.ts
+139
-20
src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue
+31
-46
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
+68
-48
No files found.
src/components/SimpleProcessDesigner/src/addNode.vue
deleted
100644 → 0
View file @
fd13eb7f
/* stylelint-disable order/properties-order */
<
template
>
<div
class=
"add-node-btn-box"
>
<div
class=
"add-node-btn"
>
<el-popover
placement=
"right-start"
v-model=
"visible"
width=
"auto"
>
<div
class=
"add-node-popover-body"
>
<a
class=
"add-node-popover-item approver"
@
click=
"addType(1)"
>
<div
class=
"item-wrapper"
>
<span
class=
"iconfont icon-approve"
></span>
</div>
<p>
审批人
</p>
</a>
<!-- TODO 暂时去掉未完成
<a
class=
"add-node-popover-item notifier"
@
click=
"addType(2)"
>
<div
class=
"item-wrapper"
>
<span
class=
"iconfont"
>
</span>
</div>
<p>
抄送人
</p>
</a>
<a
class=
"add-node-popover-item condition"
@
click=
"addType(4)"
>
<div
class=
"item-wrapper"
>
<span
class=
"iconfont"
>
</span>
</div>
<p>
条件分支
</p>
</a>
-->
<a
class=
"add-node-popover-item notifier"
@
click=
"addType(2)"
>
<div
class=
"item-wrapper"
>
<span
class=
"iconfont icon-copy"
></span>
</div>
<p>
抄送人
</p>
</a>
<a
class=
"add-node-popover-item condition"
@
click=
"addType(4)"
>
<div
class=
"item-wrapper"
>
<span
class=
"iconfont icon-exclusive"
></span>
</div>
<p>
条件分支
</p>
</a>
<a
class=
"add-node-popover-item condition"
@
click=
"addType(5)"
>
<div
class=
"item-wrapper"
>
<span
class=
"iconfont icon-parallel"
></span>
</div>
<p>
并行分支
</p>
</a>
<a
class=
"add-node-popover-item condition"
@
click=
"addType(7)"
>
<div
class=
"item-wrapper"
>
<span
class=
"iconfont icon-Inclusive"
></span>
</div>
<p>
包容分支
</p>
</a>
</div>
<template
#
reference
>
<button
class=
"btn"
type=
"button"
v-if=
"showAddButton"
>
<span><Icon
icon=
"ep:plus"
class=
"addIcon"
:size=
"14"
/></span>
</button>
</
template
>
</el-popover>
</div>
</div>
</template>
<
script
lang=
"ts"
setup
>
import
{
NodeType
}
from
'./consts'
import
{
ref
}
from
'vue'
import
{
generateUUID
}
from
'@/utils'
let
props
=
defineProps
({
childNodeP
:
{
type
:
Object
,
default
:
()
=>
({})
},
showAddButton
:
{
type
:
Boolean
,
default
:
true
}
})
let
emits
=
defineEmits
([
'update:childNodeP'
])
let
visible
=
ref
(
false
)
const
defaultFieldsPermission
=
inject
(
'defaultFieldsPermission'
)
const
addType
=
(
type
:
number
)
=>
{
visible
.
value
=
false
// 审核节点
if
(
type
===
NodeType
.
APPROVE_USER_NODE
)
{
const
data
=
{
name
:
'审核人'
,
error
:
true
,
type
:
1
,
// 审批节点配置
attributes
:
{
approveMethod
:
undefined
,
candidateStrategy
:
undefined
,
candidateParam
:
undefined
,
fieldsPermission
:
defaultFieldsPermission
},
childNode
:
props
.
childNodeP
}
emits
(
'update:childNodeP'
,
data
)
}
// 抄送节点
if
(
type
===
NodeType
.
CC_USER_NODE
)
{
const
data
=
{
name
:
'抄送人'
,
type
:
2
,
// TODO @jason:这个要不要搞成枚举?NodeType 里貌似有枚举
error
:
true
,
// 抄送节点配置
attributes
:
{
candidateStrategy
:
undefined
,
candidateParam
:
undefined
},
childNode
:
props
.
childNodeP
}
emits
(
'update:childNodeP'
,
data
)
}
// 条件分支
if
(
type
===
NodeType
.
EXCLUSIVE_NODE
)
{
const
data
=
{
name
:
'条件分支'
,
type
:
4
,
id
:
'GateWay_'
+
generateUUID
(),
childNode
:
props
.
childNodeP
,
conditionNodes
:
[
{
name
:
'分支1'
,
error
:
true
,
type
:
3
,
priorityLevel
:
1
,
conditionList
:
[],
childNode
:
null
},
{
name
:
'其它情况'
,
type
:
3
,
priorityLevel
:
2
,
conditionList
:
[],
childNode
:
null
}
]
}
emits
(
'update:childNodeP'
,
data
)
}
// 并行分支 fork
if
(
type
===
NodeType
.
PARALLEL_NODE_FORK
)
{
const
data
=
{
name
:
'并行分支_FORK'
,
type
:
5
,
id
:
'GateWay_'
+
generateUUID
(),
conditionNodes
:
[
{
name
:
'并行1'
,
error
:
true
,
type
:
3
,
childNode
:
null
},
{
name
:
'并行2'
,
type
:
3
,
childNode
:
null
}
],
childNode
:
{
id
:
'GateWay_'
+
generateUUID
(),
name
:
'并行分支_JOIN'
,
type
:
6
,
error
:
true
,
childNode
:
props
.
childNodeP
}
}
emits
(
'update:childNodeP'
,
data
)
}
// 包容分支 fork
if
(
type
===
NodeType
.
INCLUSIVE_NODE_FORK
)
{
const
data
=
{
name
:
'包容分支_FORK'
,
type
:
7
,
id
:
'GateWay_'
+
generateUUID
(),
conditionNodes
:
[
{
name
:
'分支1'
,
error
:
true
,
type
:
3
,
childNode
:
null
},
{
name
:
'其它情况'
,
type
:
3
,
childNode
:
null
}
],
childNode
:
{
id
:
'GateWay_'
+
generateUUID
(),
name
:
'包容分支_JOIN'
,
type
:
8
,
error
:
true
,
childNode
:
props
.
childNodeP
}
}
emits
(
'update:childNodeP'
,
data
)
}
// if (type != 4) {
// var data
// if (type == 1) {
// data = {
// name: '审核人',
// error: true,
// type: 1,
// // 审批节点配置
// attributes : {
// approveMethod : undefined,
// candidateStrategy: undefined,
// candidateParam: undefined
// },
// childNode: props.childNodeP
// }
// } else if (type == 2) {
// data = {
// name: '抄送人',
// type: 2,
// error: true,
// // 抄送节点配置
// attributes : {
// candidateStrategy: undefined,
// candidateParam: undefined
// },
// childNode: props.childNodeP
// }
// }
// emits('update:childNodeP', data)
// } else {
// emits('update:childNodeP', {
// name: '路由',
// type: 4,
// id : 'GateWay_'+ generateUUID(),
// childNode: props.childNodeP,
// conditionNodes: [
// {
// name: '条件1',
// error: true,
// type: 3,
// priorityLevel: 1,
// conditionList: [],
// childNode: null
// },
// {
// name: '其它情况',
// type: 3,
// priorityLevel: 2,
// conditionList: [],
// childNode: null
// }
// ]
// })
// }
}
</
script
>
<
style
scoped
lang=
"scss"
>
.add-node-btn-box
{
position
:
relative
;
display
:
inline-flex
;
width
:
240px
;
-ms-flex-negative
:
0
;
flex-shrink
:
0
;
-webkit-box-flex
:
1
;
-ms-flex-positive
:
1
;
&::before
{
position
:
absolute
;
inset
:
0
;
z-index
:
-1
;
width
:
2px
;
height
:
100%
;
margin
:
auto
;
background-color
:
#cacaca
;
content
:
''
;
}
.add-node-btn
{
display
:
flex
;
width
:
240px
;
padding
:
20px
0
32px
;
justify-content
:
center
;
flex-shrink
:
0
;
-webkit-box-flex
:
1
;
-webkit-box-pack
:
center
;
user-select
:
none
;
flex-grow
:
1
;
.btn
{
position
:
relative
;
width
:
30px
;
height
:
30px
;
line-height
:
30px
;
background
:
#3296fa
;
border
:
none
;
border-radius
:
50%
;
outline
:
none
;
box-shadow
:
0
2px
4px
0
rgba
(
0
,
0
,
0
,
0.1
);
-webkit-transition
:
all
0.3s
cubic-bezier
(
0.645
,
0.045
,
0.355
,
1
);
transition
:
all
0.3s
cubic-bezier
(
0.645
,
0.045
,
0.355
,
1
);
.addIcon
{
line-height
:
30px
;
color
:
#fff
;
}
&
:hover
{
transform
:
scale
(
1.3
);
box-shadow
:
0
13px
27px
0
rgba
(
0
,
0
,
0
,
0.1
);
}
&
:active
{
background
:
#1e83e9
;
transform
:
none
;
box-shadow
:
0
2px
4px
0
rgba
(
0
,
0
,
0
,
0.1
);
}
}
}
}
.add-node-popover-body
{
display
:
flex
;
.add-node-popover-item
{
margin-right
:
10px
;
cursor
:
pointer
;
text-align
:
center
;
flex
:
1
;
color
:
#191f25
!important
;
.item-wrapper
{
display
:
inline-block
;
width
:
80px
;
height
:
80px
;
margin-bottom
:
5px
;
background
:
#fff
;
border
:
1px
solid
#e2e2e2
;
border-radius
:
50%
;
transition
:
all
0.3s
cubic-bezier
(
0.645
,
0.045
,
0.355
,
1
);
user-select
:
none
;
.iconfont
{
font-size
:
35px
;
line-height
:
80px
;
}
}
&
.approver
{
.item-wrapper
{
color
:
#ff943e
;
}
}
&
.notifier
{
.item-wrapper
{
color
:
#3296fa
;
}
}
&
.condition
{
.item-wrapper
{
color
:
#15bc83
;
}
}
&
:hover
{
.item-wrapper
{
background
:
#3296fa
;
box-shadow
:
0
10px
20px
0
rgba
(
50
,
150
,
250
,
0.4
);
}
.iconfont
{
color
:
#fff
;
}
}
&
:active
{
.item-wrapper
{
background
:
#eaeaea
;
box-shadow
:
none
;
}
.iconfont
{
color
:
inherit
;
}
}
}
}
</
style
>
src/components/SimpleProcessDesigner/src/consts.ts
deleted
100644 → 0
View file @
fd13eb7f
export
enum
NodeType
{
//// -1 根节点流程开始节点 0 发起人 1审批 2抄送 3条件 4路由
ROOT_NODE
=
-
1
,
/**
* 发起人节点
*/
START_USER_NODE
=
0
,
/**
* 审批人节点
*/
APPROVE_USER_NODE
=
1
,
/**
* 抄送人节点
*/
CC_USER_NODE
=
2
,
/**
* 条件节点
*/
CONDITION_NODE
=
3
,
/**
* 条件分支节点
*/
EXCLUSIVE_NODE
=
4
,
/**
* 并行分支分叉节点
*/
PARALLEL_NODE_FORK
=
5
,
/**
* 并行分支聚合
*/
PARALLEL_NODE_JOIN
=
6
,
/**
* 包容分支分叉节点
*/
INCLUSIVE_NODE_FORK
=
7
,
/**
* 包容分支聚合节点
*/
INCLUSIVE_NODE_JOIN
=
8
}
export
const
NODE_BG_COLOR
=
new
Map
()
NODE_BG_COLOR
.
set
(
NodeType
.
START_USER_NODE
,
'#87, 106, 149'
)
NODE_BG_COLOR
.
set
(
NodeType
.
APPROVE_USER_NODE
,
'#255, 148, 62'
)
NODE_BG_COLOR
.
set
(
NodeType
.
CC_USER_NODE
,
'#50, 150, 250'
)
/**
* 节点的标题
*/
export
const
NODE_TITLE
=
new
Map
()
NODE_TITLE
.
set
(
NodeType
.
START_USER_NODE
,
'发起人'
)
NODE_TITLE
.
set
(
NodeType
.
APPROVE_USER_NODE
,
'审批人'
)
NODE_TITLE
.
set
(
NodeType
.
CC_USER_NODE
,
'抄送人'
)
export
type
WorkFlowNode
=
{
id
:
string
,
type
:
NodeType
,
name
:
string
,
attributes
:
any
,
// 操作人
childNode
?:
WorkFlowNode
|
undefined
,
conditionNodes
:
WorkFlowNode
[]
}
\ No newline at end of file
src/components/SimpleProcessDesigner/src/drawer/approverDrawer.vue
deleted
100644 → 0
View file @
fd13eb7f
<!-- eslint-disable vue/html-self-closing -->
<
template
>
<el-drawer
:append-to-body=
"true"
v-model=
"visible"
:show-close=
"false"
:size=
"550"
:before-close=
"saveConfig"
class=
"justify-start"
>
<template
#
header
>
<div
class=
"w-full flex flex-col"
>
<span
class=
"text-size-2xl"
>
审批设置
</span>
<el-divider
/>
</div>
</
template
>
<el-tabs
type=
"border-card"
>
<el-tab-pane
label=
"审批人"
>
<div>
<el-form
label-position=
"top"
label-width=
"100px"
>
<el-form-item
label=
"审批方式"
prop=
"approveMethod"
>
<el-select
v-model=
"candidateConfig.approveMethod"
style=
"width: 100%"
clearable
>
<el-option
v-for=
"dict in approveMethods"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"审批人规则类型"
prop=
"candidateStrategy"
>
<el-select
v-model=
"candidateConfig.candidateStrategy"
style=
"width: 100%"
clearable
@
change=
"changecandidateStrategy"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if=
"candidateConfig.candidateStrategy == 10"
label=
"指定角色"
prop=
"candidateParam"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"
candidateConfig.candidateStrategy == 20 || candidateConfig.candidateStrategy == 21
"
label=
"指定部门"
prop=
"candidateParam"
span=
"24"
>
<el-tree-select
ref=
"treeRef"
v-model=
"candidateConfig.candidateParam"
:data=
"deptTreeOptions"
:props=
"defaultProps"
empty-text=
"加载中,请稍后"
multiple
node-key=
"id"
style=
"width: 100%"
show-checkbox
/>
</el-form-item>
<el-form-item
v-if=
"candidateConfig.candidateStrategy == 22"
label=
"指定岗位"
prop=
"candidateParam"
span=
"24"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"
candidateConfig.candidateStrategy == 30 ||
candidateConfig.candidateStrategy == 31 ||
candidateConfig.candidateStrategy == 32
"
label=
"指定用户"
prop=
"candidateParam"
span=
"24"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"candidateConfig.candidateStrategy === 40"
label=
"指定用户组"
prop=
"candidateParam"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"candidateConfig.candidateStrategy === 60"
label=
"流程表达式"
prop=
"candidateParam"
>
<el-input
type=
"textarea"
v-model=
"candidateConfig.candidateParam[0]"
clearable
style=
"width: 100%"
/>
</el-form-item>
</el-form>
</div>
</el-tab-pane>
<el-tab-pane
label=
"设置字段权限"
v-if=
"formType === 10"
>
<div
class=
"field-setting-pane h-full w-full flex flex-col"
>
<div
class=
"field-setting-content mr-2 overflow-auto py-4 pr-2"
>
<div
class=
"field-container flex flex-col flex-items-start"
>
<div
class=
"mb-2 ml-4 font-bold"
>
字段权限
</div>
<div
class=
"field-body ml-4 mt-2"
>
<div
class=
"field-permit-box text-size--13px"
>
<div
class=
"field-permit-title"
>
<span
class=
"setting-title-label"
>
组件名称
</span>
<span
class=
"setting-title-label"
>
可编辑
</span>
<span
class=
"setting-title-label"
>
只读
</span>
<span
class=
"setting-title-label"
>
隐藏
</span>
</div>
<!-- <div class="field-setting-item">
<span class="field-setting-item-label">全选</span>
<span class="all-checkbox-wrap">
<el-checkbox
label=""
size="large"
/>
</span>
<span class="all-checkbox-wrap">
<el-checkbox
label=""
size="large"
/>
</span>
<span class="all-checkbox-wrap">
<el-checkbox
label=""
size="large"
/>
</span>
</div> -->
<div
class=
"field-setting-item-check"
>
<div
class=
"field-setting-item"
v-for=
"(item, index) in candidateConfig.fieldsPermission"
:key=
"index"
>
<span
class=
"field-setting-item-label"
>
{{ item.title }}
</span>
<el-radio-group
v-model=
"item.permission"
>
<div
class=
"item-radio-wrap"
>
<el-radio
value=
"1"
size=
"large"
label=
"1"
/>
</div>
<div
class=
"item-radio-wrap"
>
<el-radio
value=
"2"
size=
"large"
label=
"2"
/>
</div>
<div
class=
"item-radio-wrap"
>
<el-radio
value=
"3"
size=
"large"
label=
"3"
/>
</div>
</el-radio-group>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</el-tab-pane>
</el-tabs>
<
template
#
footer
>
<el-divider
/>
<div>
<el-button
type=
"primary"
@
click=
"saveConfig"
>
确 定
</el-button>
<el-button
@
click=
"closeDrawer"
>
取 消
</el-button>
</div>
</
template
>
</el-drawer>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
,
watch
,
computed
,
toRaw
}
from
'vue'
import
{
approveMethods
}
from
'../util'
import
{
useWorkFlowStoreWithOut
}
from
'@/store/modules/bpm/simpleWorkflow'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
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'
const
roleOptions
=
ref
<
RoleApi
.
RoleVO
[]
>
([])
// 角色列表
const
postOptions
=
ref
<
PostApi
.
PostVO
[]
>
([])
// 岗位列表
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
deptTreeOptions
=
ref
()
// 部门树
const
userGroupOptions
=
ref
<
UserGroupApi
.
UserGroupVO
[]
>
([])
// 用户组列表
const
candidateConfig
=
ref
({
candidateStrategy
:
undefined
,
candidateParam
:
[],
approveMethod
:
undefined
,
fieldsPermission
:
[]
})
const
store
=
useWorkFlowStoreWithOut
()
let
{
setApproverDrawer
,
setUserTaskConfig
}
=
store
// let approverConfig1 = computed(() => store.approverConfig1)
let
approverDrawer
=
computed
(()
=>
store
.
approverDrawer
)
const
userTaskConfig
=
computed
(()
=>
store
.
userTaskConfig
)
const
formType
=
inject
(
'formType'
)
let
visible
=
computed
({
get
()
{
return
approverDrawer
.
value
},
set
()
{
closeDrawer
()
}
})
watch
(
userTaskConfig
,
(
val
)
=>
{
if
(
val
.
value
.
attributes
)
{
candidateConfig
.
value
.
approveMethod
=
val
.
value
.
attributes
.
approveMethod
candidateConfig
.
value
.
candidateStrategy
=
val
.
value
.
attributes
.
candidateStrategy
const
candidateParamStr
=
val
.
value
.
attributes
.
candidateParam
if
(
val
.
value
.
attributes
.
candidateStrategy
===
60
)
{
candidateConfig
.
value
.
candidateParam
=
[
candidateParamStr
]
}
else
{
if
(
candidateParamStr
)
{
candidateConfig
.
value
.
candidateParam
=
candidateParamStr
.
split
(
','
).
map
((
item
)
=>
+
item
)
}
}
console
.
log
(
'val.value.attributes.fieldsPermission'
,
val
.
value
.
attributes
.
fieldsPermission
)
candidateConfig
.
value
.
fieldsPermission
=
val
.
value
.
attributes
.
fieldsPermission
}
})
// watch(approverConfig1, (val) => {
// approverConfig.value = val.value
// })
const
saveConfig
=
()
=>
{
const
rawConfig
=
toRaw
(
userTaskConfig
.
value
)
const
{
approveMethod
,
candidateStrategy
,
candidateParam
,
fieldsPermission
}
=
toRaw
(
candidateConfig
.
value
)
const
candidateParamStr
=
candidateParam
.
join
(
','
)
rawConfig
.
value
.
attributes
=
{
approveMethod
,
candidateStrategy
,
candidateParam
:
candidateParamStr
,
fieldsPermission
:
fieldsPermission
}
rawConfig
.
flag
=
true
// TODO 进行校验
// setApproverConfig({
// value: approverConfig.value,
// flag: true,
// id: approverConfig1.value.id
// })
setUserTaskConfig
({
value
:
rawConfig
.
value
,
flag
:
true
,
id
:
userTaskConfig
.
value
.
id
})
closeDrawer
()
}
const
closeDrawer
=
()
=>
{
setApproverDrawer
(
false
)
}
const
changecandidateStrategy
=
()
=>
{
candidateConfig
.
value
.
candidateParam
=
[]
}
const
handleAllCheck
=
(
event
,
type
)
=>
{
console
.
log
(
'event'
,
event
)
console
.
log
(
'type'
,
type
)
event
.
target
.
checked
=
true
let
permission
=
'1'
if
(
type
===
'edit'
&&
editAllChecked
.
value
)
{
permission
=
'1'
// TODO @jaosn:这个要不要用枚举里的哈
}
if
(
type
===
'read'
&&
readAllChecked
.
value
)
{
permission
=
'2'
}
if
(
type
===
'hide'
&&
hideAllChecked
.
value
)
{
permission
=
'3'
}
candidateConfig
.
value
.
fieldsPermission
.
forEach
((
item
)
=>
{
item
.
permission
=
permission
})
}
onMounted
(
async
()
=>
{
// 获得角色列表
roleOptions
.
value
=
await
RoleApi
.
getSimpleRoleList
()
// 获得岗位列表
postOptions
.
value
=
await
PostApi
.
getSimplePostList
()
// 获得用户列表
userOptions
.
value
=
await
UserApi
.
getSimpleUserList
()
// 获得部门列表
const
deptOptions
=
await
DeptApi
.
getSimpleDeptList
()
deptTreeOptions
.
value
=
handleTree
(
deptOptions
,
'id'
)
// 获得用户组列表
userGroupOptions
.
value
=
await
UserGroupApi
.
getUserGroupSimpleList
()
})
</
script
>
<
style
lang=
"scss"
scoped
>
//
::v-deep
.el-drawer__header
{
//
margin-bottom
:
2px
;
//
}
.field-permit-title
{
height
:
45px
;
padding
:
0
0
0
12px
;
line-height
:
32px
;
background-color
:
rgba
(
248
,
250
,
252
,
0.04
);
border
:
1px
solid
rgba
(
31
,
56
,
88
,
0.1
);
.
setting-title-label
:
first-child
{
text-align
:
left
;
}
.setting-title-label
{
display
:
inline-block
;
width
:
110px
;
padding
:
5px
0
;
font-size
:
13px
;
font-weight
:
700
;
color
:
rgba
(
0
,
0
,
0
,
0.6
);
text-align
:
center
;
}
}
.field-setting-item
{
display
:
flex
;
align-items
:
center
;
height
:
38px
;
padding-bottom
:
0
;
padding-left
:
12px
;
line-height
:
38px
;
border-right
:
1px
solid
rgba
(
31
,
56
,
88
,
0.1
);
border-bottom
:
1px
solid
rgba
(
31
,
56
,
88
,
0.1
);
border-left
:
1px
solid
rgba
(
31
,
56
,
88
,
0.1
);
.no-label
{
font-size
:
0
;
}
.field-setting-item-label
{
display
:
inline-block
;
width
:
110px
;
min-height
:
16px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
cursor
:
text
;
}
.all-checkbox-wrap
{
display
:
inline-block
;
width
:
110px
;
text-align
:
center
;
}
.item-radio-wrap
{
display
:
inline-block
;
width
:
110px
;
padding-left
:
6px
;
text-align
:
center
;
}
}
::v-deep
(
.el-radio__label
)
{
opacity
:
0
;
/* 隐藏标签文本 */
}
::v-deep
(
.el-divider--horizontal
)
{
display
:
block
;
width
:
100%
;
height
:
1px
;
margin
:
4px
0
;
border-top
:
1px
var
(
--el-border-color
)
var
(
--el-border-style
);
}
</
style
>
src/components/SimpleProcessDesigner/src/drawer/copyerDrawer.vue
deleted
100644 → 0
View file @
fd13eb7f
<
template
>
<el-drawer
:append-to-body=
"true"
v-model=
"visible"
:show-close=
"false"
:size=
"550"
:before-close=
"saveConfig"
>
<template
#
header
>
<div
class=
"copy-task-header"
>
抄送人设置
</div>
</
template
>
<div>
<el-form
label-position=
"top"
label-width=
"100px"
>
<el-form-item
label=
"选择抄送人"
prop=
"candidateStrategy"
>
<el-select
v-model=
"candidateConfig.candidateStrategy"
style=
"width: 100%"
clearable
@
change=
"changecandidateStrategy"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
v-if=
"candidateConfig.candidateStrategy == 10"
label=
"指定角色"
prop=
"candidateParam"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"candidateConfig.candidateStrategy == 20 || candidateConfig.candidateStrategy == 21"
label=
"指定部门"
prop=
"candidateParam"
span=
"24"
>
<el-tree-select
ref=
"treeRef"
v-model=
"candidateConfig.candidateParam"
:data=
"deptTreeOptions"
:props=
"defaultProps"
empty-text=
"加载中,请稍后"
multiple
node-key=
"id"
style=
"width: 100%"
show-checkbox
/>
</el-form-item>
<el-form-item
v-if=
"candidateConfig.candidateStrategy == 22"
label=
"指定岗位"
prop=
"candidateParam"
span=
"24"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"
candidateConfig.candidateStrategy == 30 ||
candidateConfig.candidateStrategy == 31 ||
candidateConfig.candidateStrategy == 32
"
label=
"指定用户"
prop=
"candidateParam"
span=
"24"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"candidateConfig.candidateStrategy === 40"
label=
"指定用户组"
prop=
"candidateParam"
>
<el-select
v-model=
"candidateConfig.candidateParam"
clearable
multiple
style=
"width: 100%"
>
<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=
"candidateConfig.candidateStrategy === 60"
label=
"流程表达式"
prop=
"candidateParam"
>
<el-input
type=
"textarea"
v-model=
"candidateConfig.candidateParam[0]"
clearable
style=
"width: 100%"
/>
</el-form-item>
</el-form>
</div>
<div
class=
"demo-drawer__footer clear"
>
<el-button
type=
"primary"
@
click=
"saveConfig"
>
确 定
</el-button>
<el-button
@
click=
"closeDrawer"
>
取 消
</el-button>
</div>
</el-drawer>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
,
watch
,
computed
,
toRaw
}
from
'vue'
import
{
useWorkFlowStoreWithOut
}
from
'@/store/modules/bpm/simpleWorkflow'
import
{
DICT_TYPE
,
getIntDictOptions
,
getDictLabel
}
from
'@/utils/dict'
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'
const
roleOptions
=
ref
<
RoleApi
.
RoleVO
[]
>
([])
// 角色列表
const
postOptions
=
ref
<
PostApi
.
PostVO
[]
>
([])
// 岗位列表
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
deptTreeOptions
=
ref
()
// 部门树
const
userGroupOptions
=
ref
<
UserGroupApi
.
UserGroupVO
[]
>
([])
// 用户组列表
const
candidateConfig
=
ref
({
candidateStrategy
:
undefined
,
candidateParam
:
[]
})
const
store
=
useWorkFlowStoreWithOut
()
const
{
setCopyerDrawer
,
setCopyerConfig
}
=
store
const
copyerDrawer
=
computed
(()
=>
store
.
copyerDrawer
)
const
copyerConfig
=
computed
(()
=>
store
.
copyerConfig
)
const
visible
=
computed
({
get
()
{
return
copyerDrawer
.
value
},
set
()
{
closeDrawer
()
}
})
watch
(
copyerConfig
,
(
val
)
=>
{
if
(
val
.
value
.
attributes
)
{
console
.
log
(
'val.value.attributes'
,
val
.
value
.
attributes
)
candidateConfig
.
value
.
candidateStrategy
=
val
.
value
.
attributes
.
candidateStrategy
const
candidateParamStr
=
val
.
value
.
attributes
.
candidateParam
if
(
val
.
value
.
attributes
.
candidateStrategy
===
60
)
{
candidateConfig
.
value
.
candidateParam
=
[
candidateParamStr
]
}
else
{
if
(
candidateParamStr
)
{
candidateConfig
.
value
.
candidateParam
=
candidateParamStr
.
split
(
','
).
map
((
item
)
=>
+
item
)
}
}
// candidateConfig.value = val.value.attributes
}
})
const
saveConfig
=
()
=>
{
const
rawConfig
=
toRaw
(
copyerConfig
.
value
)
const
{
candidateStrategy
,
candidateParam
}
=
toRaw
(
candidateConfig
.
value
)
const
candidateParamStr
=
candidateParam
.
join
(
','
)
rawConfig
.
value
.
attributes
=
{
candidateStrategy
,
candidateParam
:
candidateParamStr
}
rawConfig
.
flag
=
true
// TODO 进行校验
// setApproverConfig({
// value: approverConfig.value,
// flag: true,
// id: approverConfig1.value.id
// })
setCopyerConfig
({
value
:
rawConfig
.
value
,
flag
:
true
,
id
:
copyerConfig
.
value
.
id
})
console
.
log
(
'after is copyerConfig'
,
copyerConfig
.
value
)
closeDrawer
()
}
const
closeDrawer
=
()
=>
{
setCopyerDrawer
(
false
)
}
const
changecandidateStrategy
=
()
=>
{
candidateConfig
.
value
.
candidateParam
=
[]
}
onMounted
(
async
()
=>
{
// 获得角色列表
roleOptions
.
value
=
await
RoleApi
.
getSimpleRoleList
()
// 获得岗位列表
postOptions
.
value
=
await
PostApi
.
getSimplePostList
()
// 获得用户列表
userOptions
.
value
=
await
UserApi
.
getSimpleUserList
()
// 获得部门列表
const
deptOptions
=
await
DeptApi
.
getSimpleDeptList
()
deptTreeOptions
.
value
=
handleTree
(
deptOptions
,
'id'
)
// 获得用户组列表
userGroupOptions
.
value
=
await
UserGroupApi
.
getUserGroupSimpleList
()
})
</
script
>
<
style
lang=
"scss"
scoped
>
.copy-task-header
{
font-size
:
16px
!important
;
}
</
style
>
src/components/SimpleProcessDesigner/src/nodeWrap.vue
deleted
100644 → 0
View file @
fd13eb7f
<!-- eslint-disable vue/no-mutating-props -->
<!--
* @Date: 2022-09-21 14:41:53
* @LastEditors: StavinLi 495727881@qq.com
* @LastEditTime: 2023-05-24 15:20:24
* @FilePath: /Workflow-Vue3/src/components/nodeWrap.vue
-->
<
template
>
<div
class=
"node-wrap"
v-if=
"nodeConfig.type
<
3
"
>
<div
class=
"node-wrap-box"
:class=
"isTried && nodeConfig.error ? 'active error' : ''"
>
<div
class=
"title"
:style=
"`background: rgb($
{bgColors[nodeConfig.type]});`">
<span
v-if=
"nodeConfig.type == 0"
>
发起人
</span>
<template
v-else
>
<span
class=
"iconfont"
:class=
"nodeConfig.type === NodeType.APPROVE_USER_NODE ? 'icon-approve' : 'icon-copy'"
>
</span>
<input
v-if=
"isInput"
type=
"text"
class=
"ant-input editable-title-input"
@
blur=
"blurEvent(-1)"
@
focus=
"$event.currentTarget?.select()"
v-mountedFocus
v-model=
"nodeConfig.name"
:placeholder=
"defaultText"
/>
<span
v-else
class=
"editable-title"
@
click=
"clickEvent(-1)"
>
{{
nodeConfig
.
name
}}
</span>
<i
class=
"anticon anticon-close close"
@
click=
"delNode"
></i>
</
template
>
</div>
<div
class=
"content"
@
click=
"setPerson"
>
<div
class=
"text"
>
<span
class=
"placeholder"
v-if=
"!showText"
>
请选择{{ defaultText }}
</span>
<span
v-html=
"showText"
class=
"ellipsis-text"
v-else
></span>
</div>
<!-- <div class="icon-box">
<i class="anticon anticon-edit" @click="editNode"></i>
</div> -->
<i
class=
"anticon anticon-right arrow"
></i>
</div>
<div
class=
"error_tip"
v-if=
"isTried && nodeConfig.error"
>
<i
class=
"anticon anticon-exclamation-circle"
></i>
</div>
</div>
<addNode
v-model:childNodeP=
"nodeConfig.childNode"
/>
</div>
<div
class=
"branch-wrap"
v-if=
"nodeConfig.type == 4"
>
<div
class=
"branch-box-wrap"
>
<div
class=
"branch-box"
>
<button
class=
"add-branch"
@
click=
"addTerm(nodeConfig.type)"
>
添加条件
</button>
<div
class=
"col-box"
v-for=
"(item, index) in nodeConfig.conditionNodes"
:key=
"index"
>
<div
class=
"condition-node"
>
<div
class=
"condition-node-box"
>
<div
class=
"title-wrapper"
:style=
"`background: rgb(${bgColors[nodeConfig.type]});`"
>
<input
v-if=
"isInputList[index]"
type=
"text"
class=
"ant-input editable-title-input"
@
blur=
"blurEvent(index)"
@
focus=
"$event.currentTarget?.select()"
v-mountedFocus
v-model=
"item.name"
/>
<span
v-else
class=
"editable-title"
@
click=
"clickEvent(index)"
>
{{
item.name
}}
</span>
<!-- <span class="priority-title" @click="setPerson(item.priorityLevel)"
>优先级{{ index + 1 }}</span
> -->
<i
class=
"anticon anticon-close close"
@
click=
"delTerm(nodeConfig.type,index)"
v-if=
"nodeConfig.conditionNodes && index != nodeConfig.conditionNodes?.length - 1"
></i>
</div>
<div
class=
"auto-judge"
:class=
"isTried && item.error ? 'error active' : ''"
>
<!-- <div class="sort-left" v-if="index != 0" @click="arrTransfer(index, -1)"><</div> -->
<!-- <div
class="sort-right"
v-if="index != nodeConfig.conditionNodes.length - 1"
@click="arrTransfer(index)"
>></div
> -->
<!-- <div class="content" @click="setPerson(item.priorityLevel)">{{
conditionStr(nodeConfig, index)
}}</div> -->
<div
class=
"content"
>
{{ conditionStr(nodeConfig, index) }}
</div>
<div
class=
"error_tip"
v-if=
"isTried && item.error"
>
<i
class=
"anticon anticon-exclamation-circle"
></i>
</div>
</div>
<addNode
v-model:childNodeP=
"item.childNode"
/>
</div>
</div>
<nodeWrap
v-if=
"item.childNode"
v-model:nodeConfig=
"item.childNode"
/>
<
template
v-if=
"index == 0"
>
<div
class=
"top-left-cover-line"
></div>
<div
class=
"bottom-left-cover-line"
></div>
</
template
>
<
template
v-if=
"index == nodeConfig.conditionNodes.length - 1"
>
<div
class=
"top-right-cover-line"
></div>
<div
class=
"bottom-right-cover-line"
></div>
</
template
>
</div>
</div>
<addNode
v-model:childNodeP=
"nodeConfig.childNode"
/>
</div>
</div>
<div
class=
"branch-wrap"
v-if=
"nodeConfig.type == 5"
>
<div
class=
"branch-box-wrap"
>
<div
class=
"branch-box"
>
<button
class=
"add-branch"
@
click=
"addTerm(nodeConfig.type)"
>
添加分支
</button>
<div
class=
"col-box"
v-for=
"(item, index) in nodeConfig.conditionNodes"
:key=
"index"
>
<div
class=
"condition-node"
>
<div
class=
"condition-node-box"
>
<div
class=
"title-wrapper"
:style=
"`background: rgb(${bgColors[nodeConfig.type]});`"
>
<input
v-if=
"isInputList[index]"
type=
"text"
class=
"ant-input editable-title-input"
@
blur=
"blurEvent(index)"
@
focus=
"$event.currentTarget?.select()"
v-mountedFocus
v-model=
"item.name"
/>
<span
v-else
class=
"editable-title"
@
click=
"clickEvent(index)"
>
{{
item.name
}}
</span>
<i
class=
"anticon anticon-close close"
@
click=
"delTerm(nodeConfig.type, index)"
></i>
</div>
<div
class=
"auto-judge"
:class=
"isTried && item.error ? 'error active' : ''"
>
<div
class=
"content"
>
并行执行
</div>
<div
class=
"error_tip"
v-if=
"isTried && item.error"
>
<i
class=
"anticon anticon-exclamation-circle"
></i>
</div>
</div>
<addNode
v-model:childNodeP=
"item.childNode"
/>
</div>
</div>
<nodeWrap
v-if=
"item.childNode"
v-model:nodeConfig=
"item.childNode"
/>
<
template
v-if=
"index == 0"
>
<div
class=
"top-left-cover-line"
></div>
<div
class=
"bottom-left-cover-line"
></div>
</
template
>
<
template
v-if=
"index === nodeConfig.conditionNodes.length - 1"
>
<div
class=
"top-right-cover-line"
></div>
<div
class=
"bottom-right-cover-line"
></div>
</
template
>
</div>
</div>
<addNode
v-model:childNodeP=
"nodeConfig.childNode"
:show-add-button=
"false"
/>
</div>
</div>
<div
class=
"branch-wrap"
v-if=
"nodeConfig.type == 7"
>
<div
class=
"branch-box-wrap"
>
<div
class=
"branch-box"
>
<button
class=
"add-branch"
@
click=
"addTerm(nodeConfig.type)"
>
添加分支
</button>
<div
class=
"col-box"
v-for=
"(item, index) in nodeConfig.conditionNodes"
:key=
"index"
>
<div
class=
"condition-node"
>
<div
class=
"condition-node-box"
>
<div
class=
"title-wrapper"
:style=
"`background: rgb(${bgColors[nodeConfig.type]});`"
>
<input
v-if=
"isInputList[index]"
type=
"text"
class=
"ant-input editable-title-input"
@
blur=
"blurEvent(index)"
@
focus=
"$event.currentTarget?.select()"
v-mountedFocus
v-model=
"item.name"
/>
<span
v-else
class=
"editable-title"
@
click=
"clickEvent(index)"
>
{{ item.name }}
</span>
<i
class=
"anticon anticon-close close"
@
click=
"delTerm(nodeConfig.type,index)"
v-if=
"index != nodeConfig.conditionNodes?.length - 1"
></i>
</div>
<div
class=
"auto-judge"
:class=
"isTried && item.error ? 'error active' : ''"
>
<div
class=
"content"
>
{{ conditionStr(nodeConfig, index) }}
</div>
<div
class=
"error_tip"
v-if=
"isTried && item.error"
>
<i
class=
"anticon anticon-exclamation-circle"
></i>
</div>
</div>
<addNode
v-model:childNodeP=
"item.childNode"
/>
</div>
</div>
<nodeWrap
v-if=
"item.childNode"
v-model:nodeConfig=
"item.childNode"
/>
<
template
v-if=
"index == 0"
>
<div
class=
"top-left-cover-line"
></div>
<div
class=
"bottom-left-cover-line"
></div>
</
template
>
<
template
v-if=
"index == nodeConfig.conditionNodes.length - 1"
>
<div
class=
"top-right-cover-line"
></div>
<div
class=
"bottom-right-cover-line"
></div>
</
template
>
</div>
</div>
<addNode
v-model:childNodeP=
"nodeConfig.childNode"
:show-add-button=
"false"
/>
</div>
</div>
<div
class=
"node-wrap"
v-if=
"nodeConfig.type === NodeType.PARALLEL_NODE_JOIN || nodeConfig.type === NodeType.INCLUSIVE_NODE_JOIN"
>
<div
class=
"node-wrap-box"
>
<div
class=
"content"
>
<div
class=
"text"
>
聚合
</div>
</div>
</div>
<addNode
v-model:childNodeP=
"nodeConfig.childNode"
/>
</div>
<nodeWrap
v-if=
"nodeConfig.childNode"
v-model:nodeConfig=
"nodeConfig.childNode"
/>
</template>
<
script
lang=
"ts"
setup
>
import
addNode
from
'./addNode.vue'
import
{
onMounted
,
ref
,
watch
,
getCurrentInstance
,
computed
}
from
'vue'
import
{
conditionStr
,
setApproverStr
,
copyerStr
,
bgColors
,
placeholderList
,
getApproverShowText
}
from
'./util'
import
{
WorkFlowNode
,
NodeType
}
from
'./consts'
import
{
useWorkFlowStoreWithOut
}
from
'@/store/modules/bpm/simpleWorkflow'
let
_uid
=
getCurrentInstance
().
uid
import
{
generateUUID
}
from
'@/utils'
let
props
=
defineProps
({
nodeConfig
:
{
type
:
Object
as
()
=>
WorkFlowNode
,
default
:
()
=>
({})
as
WorkFlowNode
}
})
let
defaultText
=
computed
(()
=>
{
return
placeholderList
[
props
.
nodeConfig
.
type
]
})
const
isInputList
=
ref
<
boolean
[]
>
([])
const
isInput
=
ref
<
boolean
>
(
false
)
const
resetConditionNodesErr
=
()
=>
{
for
(
var
i
=
0
;
i
<
props
.
nodeConfig
.
conditionNodes
.
length
;
i
++
)
{
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
[
i
].
error
=
conditionStr
(
props
.
nodeConfig
,
i
)
==
'请设置条件'
&&
i
!=
props
.
nodeConfig
.
conditionNodes
.
length
-
1
}
}
onMounted
(()
=>
{
if
(
props
.
nodeConfig
.
type
==
1
)
{
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
error
=
!
setApproverStr
(
props
.
nodeConfig
)
}
else
if
(
props
.
nodeConfig
.
type
==
2
)
{
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
error
=
!
copyerStr
(
props
.
nodeConfig
)
}
else
if
(
props
.
nodeConfig
.
type
==
4
)
{
resetConditionNodesErr
()
}
})
let
emits
=
defineEmits
([
'update:nodeConfig'
])
let
store
=
useWorkFlowStoreWithOut
()
let
{
setApproverDrawer
,
setCopyerDrawer
,
// setCondition,
setCopyerConfig
,
// setConditionsConfig,
setUserTaskConfig
}
=
store
// ???
const
isTried
=
computed
(()
=>
store
.
isTried
)
// 审批节点的配置
const
userTaskConfig
=
computed
(()
=>
store
.
userTaskConfig
)
// 抄送节点的配置
const
copyerConfig
=
computed
(()
=>
store
.
copyerConfig
)
// let conditionsConfig1 = computed(() => store.conditionsConfig1)
const
showText
=
computed
(()
=>
{
if
(
props
.
nodeConfig
.
type
==
0
)
return
'发起人'
if
(
props
.
nodeConfig
.
type
==
1
)
{
if
(
props
.
nodeConfig
.
attributes
)
{
return
getApproverShowText
(
props
.
nodeConfig
.
attributes
.
approveMethod
,
props
.
nodeConfig
.
attributes
.
candidateStrategy
)
}
else
{
return
''
}
}
if
(
props
.
nodeConfig
.
type
===
2
)
{
if
(
props
.
nodeConfig
.
attributes
)
{
return
copyerStr
(
props
.
nodeConfig
.
attributes
.
candidateStrategy
)
}
else
{
return
''
}
}
return
''
})
watch
(
userTaskConfig
,
(
approver
)
=>
{
if
(
approver
.
flag
&&
approver
.
id
===
_uid
)
{
emits
(
'update:nodeConfig'
,
approver
.
value
)
}
})
watch
(
copyerConfig
,
(
copyer
)
=>
{
console
.
log
(
'copyer'
,
copyer
)
if
(
copyer
.
flag
&&
copyer
.
id
===
_uid
)
{
console
.
log
(
'copyer id is equal'
,
copyer
)
emits
(
'update:nodeConfig'
,
copyer
.
value
)
}
})
// watch(conditionsConfig1, (condition) => {
// if (condition.flag && condition.id === _uid) {
// emits('update:nodeConfig', condition.value)
// }
// })
const
clickEvent
=
(
index
)
=>
{
if
(
index
>=
0
)
{
isInputList
.
value
[
index
]
=
true
}
else
{
isInput
.
value
=
true
}
}
const
blurEvent
=
(
index
)
=>
{
if
(
index
>=
0
)
{
isInputList
.
value
[
index
]
=
false
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
[
index
].
name
=
props
.
nodeConfig
.
conditionNodes
[
index
].
name
||
'条件'
}
else
{
isInput
.
value
=
false
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
name
=
props
.
nodeConfig
.
name
||
defaultText
}
}
const
delNode
=
()
=>
{
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
.
childNode
)
}
const
addTerm
=
(
type
:
number
)
=>
{
const
len
=
props
.
nodeConfig
.
conditionNodes
.
length
let
lastIndex
=
props
.
nodeConfig
.
conditionNodes
.
length
-
1
let
nodeName
=
'分支'
+
len
if
(
type
===
NodeType
.
PARALLEL_NODE_FORK
)
{
nodeName
=
'并行'
+
(
len
+
1
);
lastIndex
=
props
.
nodeConfig
.
conditionNodes
.
length
;
}
const
conditionData
=
{
id
:
'SequenceFlow'
+
generateUUID
(),
name
:
nodeName
,
type
:
NodeType
.
CONDITION_NODE
,
childNode
:
undefined
,
conditionNodes
:[],
attributes
:
undefined
};
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
.
splice
(
lastIndex
,
0
,
conditionData
)
resetConditionNodesErr
()
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
)
}
const
delTerm
=
(
nodeType
:
number
,
index
:
number
)
=>
{
if
(
props
.
nodeConfig
.
conditionNodes
)
{
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
.
splice
(
index
,
1
)
if
(
nodeType
===
NodeType
.
PARALLEL_NODE_FORK
)
{
props
.
nodeConfig
.
conditionNodes
.
map
((
item
,
index
)
=>
{
item
.
name
=
`并行
${
index
+
1
}
`
})
}
else
{
props
.
nodeConfig
.
conditionNodes
.
map
((
item
,
index
)
=>
{
// item.priorityLevel = index + 1
if
(
index
!==
props
.
nodeConfig
.
conditionNodes
.
length
-
1
)
{
item
.
name
=
`分支
${
index
+
1
}
`
}
})
}
resetConditionNodesErr
()
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
)
if
(
props
.
nodeConfig
.
conditionNodes
.
length
==
1
)
{
if
(
nodeType
===
NodeType
.
PARALLEL_NODE_FORK
||
nodeType
===
NodeType
.
INCLUSIVE_NODE_FORK
)
{
const
joinNode
=
props
.
nodeConfig
.
childNode
;
if
(
joinNode
?.
childNode
)
{
if
(
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
)
{
reData
(
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
,
joinNode
?.
childNode
)
}
else
{
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
=
joinNode
?.
childNode
}
}
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
)
}
else
{
if
(
props
.
nodeConfig
.
childNode
)
{
if
(
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
)
{
reData
(
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
,
props
.
nodeConfig
.
childNode
)
}
else
{
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
=
props
.
nodeConfig
.
childNode
}
}
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
.
conditionNodes
[
0
].
childNode
)
}
}
}
}
const
reData
=
(
data
,
addData
)
=>
{
if
(
!
data
.
childNode
)
{
data
.
childNode
=
addData
}
else
{
reData
(
data
.
childNode
,
addData
)
}
}
const
setPerson
=
(
priorityLevel
)
=>
{
console
.
log
(
'priorityLevel'
,
priorityLevel
)
const
{
type
}
=
props
.
nodeConfig
console
.
log
(
'type'
,
type
)
if
(
type
==
0
)
{
// setPromoter(true)
}
else
if
(
type
==
1
)
{
setApproverDrawer
(
true
)
// if (_uid === userTaskConfig.value.id) {
// showText = userTaskConfig.value.showText
// }
setUserTaskConfig
({
value
:
{
...
JSON
.
parse
(
JSON
.
stringify
(
props
.
nodeConfig
)),
id
:
'Activity_'
+
_uid
},
flag
:
false
,
id
:
_uid
})
}
else
if
(
type
==
2
)
{
setCopyerDrawer
(
true
)
setCopyerConfig
({
value
:
{
...
JSON
.
parse
(
JSON
.
stringify
(
props
.
nodeConfig
)),
id
:
'Activity_'
+
_uid
},
flag
:
false
,
id
:
_uid
})
}
else
{
// setCondition(true)
// setConditionsConfig({
// value: {
// ...JSON.parse(JSON.stringify(props.nodeConfig)),
// id: 'Gateway_' + _uid
// },
// priorityLevel,
// flag: false,
// id: _uid
// })
}
}
// const arrTransfer = (index, type = 1) => {
// //向左-1,向右1
// // eslint-disable-next-line vue/no-mutating-props
// props.nodeConfig.conditionNodes[index] = props.nodeConfig.conditionNodes.splice(
// index + type,
// 1,
// props.nodeConfig.conditionNodes[index]
// )[0]
// props.nodeConfig.conditionNodes.map((item, index) => {
// item.priorityLevel = index + 1
// })
// resetConditionNodesErr()
// emits('update:nodeConfig', props.nodeConfig)
// }
</
script
>
<
style
lang=
"scss"
scoped
>
.ellipsis-text
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
.start-event-node
{
color
:
#191f2566
;
text-align
:
left
;
border-radius
:
50%
;
}
.start-event-node-circle
{
display
:
flex
;
width
:
40px
;
height
:
40px
;
align-items
:
center
;
justify-content
:
center
;
//
margin
:
auto
;
//
background
:
#dbdcdc
;
font-size
:
16px
;
color
:
#f8f8fa
;
background-image
:
linear-gradient
(
90deg
,
#ff6a00
,
#f78b3e
),
linear-gradient
(
#ff6a00
,
#ff6a00
);
border-radius
:
50%
;
}
.start-event-node-text
{
margin-top
:
5px
;
font-size
:
14px
;
text-align
:
center
;
}
</
style
>
src/components/SimpleProcessDesigner/src/util.ts
deleted
100644 → 0
View file @
fd13eb7f
// @ts-ignore
import
{
DictDataVO
}
from
'@/api/system/dict/types'
import
{
DICT_TYPE
,
getDictLabel
}
from
'@/utils/dict'
/**
* todo
*/
export
const
arrToStr
=
(
arr
?:
[{
name
:
string
}])
=>
{
if
(
arr
)
{
return
arr
.
map
((
item
)
=>
{
return
item
.
name
})
.
toString
()
}
}
export
const
setApproverStr
=
(
nodeConfig
:
any
)
=>
{
if
(
nodeConfig
.
settype
==
1
)
{
if
(
nodeConfig
.
nodeUserList
.
length
==
1
)
{
return
nodeConfig
.
nodeUserList
[
0
].
name
}
else
if
(
nodeConfig
.
nodeUserList
.
length
>
1
)
{
if
(
nodeConfig
.
examineMode
==
1
)
{
return
arrToStr
(
nodeConfig
.
nodeUserList
)
}
else
if
(
nodeConfig
.
examineMode
==
2
)
{
return
nodeConfig
.
nodeUserList
.
length
+
'人会签'
}
}
}
else
if
(
nodeConfig
.
settype
==
2
)
{
const
level
=
nodeConfig
.
directorLevel
==
1
?
'直接主管'
:
'第'
+
nodeConfig
.
directorLevel
+
'级主管'
if
(
nodeConfig
.
examineMode
==
1
)
{
return
level
}
else
if
(
nodeConfig
.
examineMode
==
2
)
{
return
level
+
'会签'
}
}
else
if
(
nodeConfig
.
settype
==
4
)
{
if
(
nodeConfig
.
selectRange
==
1
)
{
return
'发起人自选'
}
else
{
if
(
nodeConfig
.
nodeUserList
.
length
>
0
)
{
if
(
nodeConfig
.
selectRange
==
2
)
{
return
'发起人自选'
}
else
{
return
'发起人从'
+
nodeConfig
.
nodeUserList
[
0
].
name
+
'中自选'
}
}
else
{
return
''
}
}
}
else
if
(
nodeConfig
.
settype
==
5
)
{
return
'发起人自己'
}
else
if
(
nodeConfig
.
settype
==
7
)
{
return
'从直接主管到通讯录中级别最高的第'
+
nodeConfig
.
examineEndDirectorLevel
+
'个层级主管'
}
}
export
const
approveMethods
:
DictDataVO
[]
=
[
{
label
:
'单人审批'
,
value
:
1
}
// { label: '多人审批(所有人审批通过)', value: 2 }
// TODO 更多的类型
];
export
const
getApproverShowText
=
(
approveMethod
:
number
,
candidateStrategy
:
number
)
=>
{
let
appoveMethodText
=
'单人审批'
if
(
candidateStrategy
)
{
approveMethods
.
forEach
((
item
)
=>
{
if
(
item
.
value
==
approveMethod
)
{
appoveMethodText
=
item
.
label
}
})
const
strategyText
=
getDictLabel
(
DICT_TYPE
.
BPM_TASK_CANDIDATE_STRATEGY
,
candidateStrategy
)
return
`审批方式:
${
appoveMethodText
}
<br/>
审批人规则类型:按
${
strategyText
}
`
}
else
{
return
''
}
}
export
const
copyerStr
=
(
candidateStrategy
:
number
)
=>
{
// if (nodeConfig.nodeUserList.length != 0) {
// return arrToStr(nodeConfig.nodeUserList)
// } else {
// if (nodeConfig.ccSelfSelectFlag == 1) {
// return '发起人自选'
// }
// }
console
.
log
(
'candidateStrategy'
,
candidateStrategy
);
if
(
candidateStrategy
)
{
const
strategyText
=
getDictLabel
(
DICT_TYPE
.
BPM_TASK_CANDIDATE_STRATEGY
,
candidateStrategy
)
return
`抄送人类型:按
${
strategyText
}
`
}
else
{
return
''
}
}
export
const
conditionStr
=
(
nodeConfig
,
index
)
=>
{
// const { conditionList, nodeUserList } = nodeConfig.conditionNodes[index]
// if (conditionList.length == 0) {
// return index == nodeConfig.conditionNodes.length - 1 &&
// nodeConfig.conditionNodes[0].conditionList.length != 0
// ? '其他条件进入此流程'
// : '请设置条件'
// return index == nodeConfig.conditionNodes.length - 1 &&
// nodeConfig.conditionNodes[0].conditionList.length != 0
// ? '其他条件进入此流程'
// : '请设置条件'
// console.log('index===>', index);
// console.log('nodeConfig.conditionNodes.length===>', nodeConfig.conditionNodes.length);
if
(
index
===
nodeConfig
.
conditionNodes
.
length
-
1
)
{
return
'其它情况将进入该分支'
}
else
{
return
'请设置条件'
}
// } else {
// let str = ''
// for (let i = 0; i < conditionList.length; i++) {
// const {
// columnId,
// columnType,
// showType,
// showName,
// optType,
// zdy1,
// opt1,
// zdy2,
// opt2,
// fixedDownBoxValue
// } = conditionList[i]
// if (columnId == 0) {
// if (nodeUserList.length != 0) {
// str += '发起人属于:'
// str +=
// nodeUserList
// .map((item) => {
// return item.name
// })
// .join('或') + ' 并且 '
// }
// }
// if (columnType == 'String' && showType == '3') {
// if (zdy1) {
// str += showName + '属于:' + dealStr(zdy1, JSON.parse(fixedDownBoxValue)) + ' 并且 '
// }
// }
// if (columnType == 'Double') {
// if (optType != 6 && zdy1) {
// const optTypeStr = ['', '<', '>', '≤', '=', '≥'][optType]
// str += `${showName} ${optTypeStr} ${zdy1} 并且 `
// } else if (optType == 6 && zdy1 && zdy2) {
// str += `${zdy1} ${opt1} ${showName} ${opt2} ${zdy2} 并且 `
// }
// }
// }
// str ? str.substring(0, str.length - 4) :
return
'请设置条件'
// }
}
// export const dealStr = (str: string, obj) => {
// const arr = []
// const list = str.split(',')
// for (const elem in obj) {
// list.map((item) => {
// if (item == elem) {
// arr.push(obj[elem].value)
// }
// })
// }
// return arr.join('或')
// }
export
const
removeEle
=
(
arr
,
elem
,
key
=
'id'
)
=>
{
let
includesIndex
arr
.
map
((
item
,
index
)
=>
{
if
(
item
[
key
]
==
elem
[
key
])
{
includesIndex
=
index
}
})
arr
.
splice
(
includesIndex
,
1
)
}
export
const
bgColors
=
[
'87, 106, 149'
,
'255, 148, 62'
,
'50, 150, 250'
,
'50, 150, 250'
,
'248, 107, 248'
,
'244, 118, 118'
,
'23, 148, 46'
,
'23, 148, 46'
]
export
const
placeholderList
=
[
'发起人'
,
'审核人'
,
'抄送人'
]
export
const
setTypes
=
[
{
value
:
1
,
label
:
'指定成员'
},
{
value
:
2
,
label
:
'主管'
},
{
value
:
4
,
label
:
'发起人自选'
},
{
value
:
5
,
label
:
'发起人自己'
},
{
value
:
7
,
label
:
'连续多级主管'
}
]
export
const
selectModes
=
[
{
value
:
1
,
label
:
'选一个人'
},
{
value
:
2
,
label
:
'选多个人'
}
]
export
const
selectRanges
=
[
{
value
:
1
,
label
:
'全公司'
},
{
value
:
2
,
label
:
'指定成员'
},
{
value
:
3
,
label
:
'指定角色'
}
]
export
const
optTypes
=
[
{
value
:
'1'
,
label
:
'小于'
},
{
value
:
'2'
,
label
:
'大于'
},
{
value
:
'3'
,
label
:
'小于等于'
},
{
value
:
'4'
,
label
:
'等于'
},
{
value
:
'5'
,
label
:
'大于等于'
},
{
value
:
'6'
,
label
:
'介于两个数之间'
}
]
src/components/SimpleProcessDesigner/theme/iconfont.ttf
deleted
100644 → 0
View file @
fd13eb7f
File deleted
src/components/SimpleProcessDesigner/theme/iconfont.woff
deleted
100644 → 0
View file @
fd13eb7f
File deleted
src/components/SimpleProcessDesigner/theme/iconfont.woff2
deleted
100644 → 0
View file @
fd13eb7f
File deleted
src/components/SimpleProcessDesigner/theme/workflow.css
deleted
100644 → 0
View file @
fd13eb7f
.clearfix
{
zoom
:
1
}
.clearfix
:after
,
.clearfix
:before
{
content
:
""
;
display
:
table
}
.clearfix
:after
{
clear
:
both
}
@font-face
{
font-family
:
anticon
;
font-display
:
fallback
;
src
:
url("https://at.alicdn.com/t/font_148784_v4ggb6wrjmkotj4i.eot")
;
src
:
url("https://at.alicdn.com/t/font_148784_v4ggb6wrjmkotj4i.woff")
format
(
"woff"
),
url("https://at.alicdn.com/t/font_148784_v4ggb6wrjmkotj4i.ttf")
format
(
"truetype"
),
url("https://at.alicdn.com/t/font_148784_v4ggb6wrjmkotj4i.svg#iconfont")
format
(
"svg"
)
}
.anticon
{
display
:
inline-block
;
font-style
:
normal
;
vertical-align
:
baseline
;
text-align
:
center
;
text-transform
:
none
;
line-height
:
1
;
text-rendering
:
optimizeLegibility
;
-webkit-font-smoothing
:
antialiased
;
-moz-osx-font-smoothing
:
grayscale
}
.anticon
:before
{
display
:
block
;
font-family
:
anticon
!important
}
.anticon-close
:before
{
content
:
"\E633"
}
.anticon-right
:before
{
content
:
"\E61F"
}
.anticon-exclamation-circle
{
color
:
rgb
(
242
,
86
,
67
)
}
.anticon-exclamation-circle
:before
{
content
:
"\E62C"
}
.anticon-left
:before
{
content
:
"\E620"
}
.anticon-close-circle
:before
{
content
:
"\E62E"
}
.ant-btn
{
line-height
:
1.5
;
display
:
inline-block
;
font-weight
:
400
;
text-align
:
center
;
touch-action
:
manipulation
;
cursor
:
pointer
;
background-image
:
none
;
border
:
1px
solid
transparent
;
white-space
:
nowrap
;
padding
:
0
15px
;
font-size
:
14px
;
border-radius
:
4px
;
height
:
32px
;
user-select
:
none
;
transition
:
all
.3s
cubic-bezier
(
.645
,
.045
,
.355
,
1
);
position
:
relative
;
color
:
rgba
(
0
,
0
,
0
,
.65
);
background-color
:
#fff
;
border-color
:
#d9d9d9
}
.ant-btn
>
.anticon
{
line-height
:
1
}
.ant-btn
,
.ant-btn
:active
,
.ant-btn
:focus
{
outline
:
0
}
.ant-btn
>
a
:only-child
{
color
:
currentColor
}
.ant-btn
>
a
:only-child:after
{
content
:
""
;
position
:
absolute
;
top
:
0
;
left
:
0
;
bottom
:
0
;
right
:
0
;
background
:
transparent
}
.ant-btn
:focus
,
.ant-btn
:hover
{
color
:
#40a9ff
;
background-color
:
#fff
;
border-color
:
#40a9ff
}
.ant-btn
:focus
>
a
:only-child
,
.ant-btn
:hover
>
a
:only-child
{
color
:
currentColor
}
.ant-btn
:focus
>
a
:only-child:after
,
.ant-btn
:hover
>
a
:only-child:after
{
content
:
""
;
position
:
absolute
;
top
:
0
;
left
:
0
;
bottom
:
0
;
right
:
0
;
background
:
transparent
}
.ant-btn.active
,
.ant-btn
:active
{
color
:
#096dd9
;
background-color
:
#fff
;
border-color
:
#096dd9
}
.ant-btn.active
>
a
:only-child
,
.ant-btn
:active
>
a
:only-child
{
color
:
currentColor
}
.ant-btn.active
>
a
:only-child:after
,
.ant-btn
:active
>
a
:only-child:after
{
content
:
""
;
position
:
absolute
;
top
:
0
;
left
:
0
;
bottom
:
0
;
right
:
0
;
background
:
transparent
}
.ant-btn.active
,
.ant-btn
:active
,
.ant-btn
:focus
,
.ant-btn
:hover
{
background
:
#fff
;
text-decoration
:
none
}
.ant-btn
>
i
,
.ant-btn
>
span
{
pointer-events
:
none
}
.ant-btn
:before
{
position
:
absolute
;
top
:
-1px
;
left
:
-1px
;
bottom
:
-1px
;
right
:
-1px
;
background
:
#fff
;
opacity
:
.35
;
content
:
""
;
border-radius
:
inherit
;
z-index
:
1
;
transition
:
opacity
.2s
;
pointer-events
:
none
;
display
:
none
}
.ant-btn
.anticon
{
transition
:
margin-left
.3s
cubic-bezier
(
.645
,
.045
,
.355
,
1
)
}
.ant-btn
:active
>
span
,
.ant-btn
:focus
>
span
{
position
:
relative
}
.ant-btn
>
.anticon
+
span
,
.ant-btn
>
span
+
.anticon
{
margin-left
:
8px
}
.ant-input
{
font-family
:
Chinese
Quote
,
-apple-system
,
BlinkMacSystemFont
,
Segoe
UI
,
PingFang
SC
,
Hiragino
Sans
GB
,
Microsoft
YaHei
,
Helvetica
Neue
,
Helvetica
,
Arial
,
sans-serif
;
font-variant
:
tabular-nums
;
box-sizing
:
border-box
;
margin
:
0
;
padding
:
0
;
list-style
:
none
;
position
:
relative
;
display
:
inline-block
;
padding
:
4px
11px
;
width
:
100%
;
height
:
32px
;
font-size
:
14px
;
line-height
:
1.5
;
color
:
rgba
(
0
,
0
,
0
,
.65
);
background-color
:
#fff
;
background-image
:
none
;
border
:
1px
solid
#d9d9d9
;
border-radius
:
4px
;
transition
:
all
.3s
}
.ant-input
::-moz-placeholder
{
color
:
#bfbfbf
;
opacity
:
1
}
.ant-input
:-ms-input-placeholder
{
color
:
#bfbfbf
}
.ant-input
::-webkit-input-placeholder
{
color
:
#bfbfbf
}
.ant-input
:focus
,
.ant-input
:hover
{
border-color
:
#40a9ff
;
border-right-width
:
1px
!important
}
.ant-input
:focus
{
outline
:
0
;
box-shadow
:
0
0
0
2px
rgba
(
24
,
144
,
255
,
.2
)
}
textarea
.ant-input
{
max-width
:
100%
;
height
:
auto
;
vertical-align
:
bottom
;
transition
:
all
.3s
,
height
0s
;
min-height
:
32px
}
a
,
abbr
,
acronym
,
address
,
applet
,
article
,
aside
,
audio
,
b
,
big
,
blockquote
,
body
,
canvas
,
caption
,
center
,
cite
,
code
,
dd
,
del
,
details
,
dfn
,
div
,
dl
,
dt
,
em
,
fieldset
,
figcaption
,
figure
,
footer
,
form
,
h1
,
h2
,
h3
,
h4
,
h5
,
h6
,
header
,
hgroup
,
html
,
i
,
iframe
,
img
,
ins
,
kbd
,
label
,
legend
,
li
,
mark
,
menu
,
nav
,
object
,
ol
,
p
,
pre
,
q
,
s
,
samp
,
section
,
small
,
span
,
strike
,
strong
,
sub
,
summary
,
sup
,
table
,
tbody
,
td
,
tfoot
,
th
,
thead
,
time
,
tr
,
tt
,
u
,
ul
,
var
,
video
{
margin
:
0
;
padding
:
0
;
border
:
0
;
outline
:
0
;
font-size
:
100%
;
font
:
inherit
;
vertical-align
:
baseline
}
*,
:after
,
:before
{
-webkit-box-sizing
:
border-box
;
-moz-box-sizing
:
border-box
;
box-sizing
:
border-box
}
html
{
font-family
:
sans-serif
;
-ms-text-size-adjust
:
100%
;
-webkit-text-size-adjust
:
100%
}
body
,
html
{
font-size
:
14px
}
body
{
font-family
:
Microsoft
Yahei
,
Lucida
Grande
,
Lucida
Sans
Unicode
,
Helvetica
,
Arial
,
Verdana
,
sans-serif
;
line-height
:
1.6
;
background-color
:
#fff
;
position
:
static
!important
;
-webkit-tap-highlight-color
:
rgba
(
0
,
0
,
0
,
0
)
}
ol
,
ul
{
list-style-type
:
none
}
b
,
strong
{
font-weight
:
700
}
img
{
border
:
0
}
button
,
input
,
select
,
textarea
{
font-family
:
inherit
;
font-size
:
100%
;
margin
:
0
}
textarea
{
overflow
:
auto
;
vertical-align
:
top
;
-webkit-appearance
:
none
}
button
,
input
{
line-height
:
normal
}
button
,
select
{
text-transform
:
none
}
button
,
html
input
[
type
=
button
],
input
[
type
=
reset
],
input
[
type
=
submit
]
{
-webkit-appearance
:
button
;
cursor
:
pointer
}
input
[
type
=
search
]
{
-webkit-appearance
:
textfield
;
-moz-box-sizing
:
content-box
;
-webkit-box-sizing
:
content-box
;
box-sizing
:
content-box
}
input
[
type
=
search
]
::-webkit-search-cancel-button
,
input
[
type
=
search
]
::-webkit-search-decoration
{
-webkit-appearance
:
none
}
button
::-moz-focus-inner
,
input
::-moz-focus-inner
{
border
:
0
;
padding
:
0
}
table
{
width
:
100%
;
border-spacing
:
0
;
border-collapse
:
collapse
}
table
,
td
,
th
{
border
:
0
}
td
,
th
{
padding
:
0
;
vertical-align
:
top
}
th
{
font-weight
:
700
;
text-align
:
left
}
thead
th
{
white-space
:
nowrap
}
a
{
text-decoration
:
none
;
cursor
:
pointer
;
color
:
#3296fa
}
a
:active
,
a
:hover
{
outline
:
0
;
color
:
#3296fa
}
small
{
font-size
:
80%
}
body
,
html
{
font-size
:
12px
!important
;
color
:
#191f25
!important
;
background
:
#f6f6f6
!important
}
.wrap
{
display
:
-webkit-box
;
display
:
-ms-flexbox
;
display
:
flex
;
-webkit-box-orient
:
vertical
;
-webkit-box-direction
:
normal
;
-ms-flex-direction
:
column
;
flex-direction
:
column
;
height
:
100%
}
/* @font-face {
font-family: IconFont;
src: url("//at.alicdn.com/t/font_135284_ph2thxxbzgf.eot");
src: url("//at.alicdn.com/t/font_135284_ph2thxxbzgf.eot?#iefix") format("embedded-opentype"), url("//at.alicdn.com/t/font_135284_ph2thxxbzgf.woff") format("woff"), url("//at.alicdn.com/t/font_135284_ph2thxxbzgf.ttf") format("truetype"), url("//at.alicdn.com/t/font_135284_ph2thxxbzgf.svg#IconFont") format("svg")
}
.iconfont {
font-family: IconFont!important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: .2px;
-moz-osx-font-smoothing: grayscale
} */
@font-face
{
font-family
:
"iconfont"
;
/* Project id 4495938 */
src
:
url('iconfont.woff2?t=1712392083512')
format
(
'woff2'
),
url('iconfont.woff?t=1712392083512')
format
(
'woff'
),
url('iconfont.ttf?t=1712392083512')
format
(
'truetype'
);
}
.iconfont
{
font-family
:
"iconfont"
!important
;
font-size
:
16px
;
font-style
:
normal
;
-webkit-font-smoothing
:
antialiased
;
-moz-osx-font-smoothing
:
grayscale
;
}
.icon-Inclusive
:before
{
content
:
"\e602"
;
}
.icon-copy
:before
{
content
:
"\e7eb"
;
}
.icon-handle
:before
{
content
:
"\e61c"
;
}
.icon-exclusive
:before
{
content
:
"\e717"
;
}
.icon-approve
:before
{
content
:
"\e715"
;
}
.icon-parallel
:before
{
content
:
"\e688"
;
}
.fd-nav
{
position
:
fixed
;
top
:
0
;
left
:
0
;
right
:
0
;
z-index
:
997
;
width
:
100%
;
height
:
60px
;
font-size
:
14px
;
color
:
#fff
;
background
:
#3296fa
;
display
:
flex
;
align-items
:
center
}
.fd-nav
>*
{
flex
:
1
;
width
:
100%
}
.fd-nav
.fd-nav-left
{
display
:
-webkit-box
;
display
:
flex
;
align-items
:
center
}
.fd-nav
.fd-nav-center
{
flex
:
none
;
width
:
600px
;
text-align
:
center
}
.fd-nav
.fd-nav-right
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-end
;
text-align
:
right
}
.fd-nav
.fd-nav-back
{
display
:
inline-block
;
width
:
60px
;
height
:
60px
;
font-size
:
22px
;
border-right
:
1px
solid
#1583f2
;
text-align
:
center
;
cursor
:
pointer
}
.fd-nav
.fd-nav-back
:hover
{
background
:
#5af
}
.fd-nav
.fd-nav-back
:active
{
background
:
#1583f2
}
.fd-nav
.fd-nav-back
.anticon
{
line-height
:
60px
}
.fd-nav
.fd-nav-title
{
width
:
0
;
flex
:
1
;
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
padding
:
0
15px
}
.fd-nav
a
{
color
:
#fff
;
margin-left
:
12px
}
.fd-nav
.button-publish
{
min-width
:
80px
;
margin-left
:
4px
;
margin-right
:
15px
;
color
:
#3296fa
;
border-color
:
#fff
}
.fd-nav
.button-publish.ant-btn
:focus
,
.fd-nav
.button-publish.ant-btn
:hover
{
color
:
#3296fa
;
border-color
:
#fff
;
box-shadow
:
0
10px
20px
0
rgba
(
0
,
0
,
0
,
.3
)
}
.fd-nav
.button-publish.ant-btn
:active
{
color
:
#3296fa
;
background
:
#d6eaff
;
box-shadow
:
none
}
.fd-nav
.button-preview
{
min-width
:
80px
;
margin-left
:
16px
;
margin-right
:
4px
;
color
:
#fff
;
border-color
:
#fff
;
background
:
transparent
}
.fd-nav
.button-preview.ant-btn
:focus
,
.fd-nav
.button-preview.ant-btn
:hover
{
color
:
#fff
;
border-color
:
#fff
;
background
:
#59acfc
}
.fd-nav
.button-preview.ant-btn
:active
{
color
:
#fff
;
border-color
:
#fff
;
background
:
#2186ef
}
.fd-nav-content
{
position
:
fixed
;
top
:
60px
;
left
:
0
;
right
:
0
;
bottom
:
0
;
z-index
:
1
;
overflow-x
:
hidden
;
overflow-y
:
auto
;
padding-bottom
:
30px
}
.error-modal-desc
{
font-size
:
13px
;
color
:
rgba
(
25
,
31
,
37
,
.56
);
line-height
:
22px
;
margin-bottom
:
14px
}
.error-modal-list
{
height
:
200px
;
overflow-y
:
auto
;
margin-right
:
-25px
;
padding-right
:
25px
}
.error-modal-item
{
padding
:
10px
20px
;
line-height
:
21px
;
background
:
#f6f6f6
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
8px
;
border-radius
:
4px
}
.error-modal-item-label
{
flex
:
none
;
font-size
:
15px
;
color
:
rgba
(
25
,
31
,
37
,
.56
);
padding-right
:
10px
}
.error-modal-item-content
{
text-align
:
right
;
flex
:
1
;
font-size
:
13px
;
color
:
#191f25
}
#body
.blur
{
-webkit-filter
:
blur
(
3px
);
filter
:
blur
(
3px
)
}
.zoom
{
display
:
flex
;
position
:
fixed
;
-webkit-box-align
:
center
;
-ms-flex-align
:
center
;
align-items
:
center
;
-webkit-box-pack
:
justify
;
-ms-flex-pack
:
justify
;
justify-content
:
space-between
;
height
:
40px
;
width
:
125px
;
right
:
40px
;
margin-top
:
30px
;
z-index
:
10
}
.zoom
.zoom-in
,
.zoom
.zoom-out
{
width
:
30px
;
height
:
30px
;
background
:
#fff
;
color
:
#c1c1cd
;
cursor
:
pointer
;
background-size
:
100%
;
background-repeat
:
no-repeat
}
.zoom
.zoom-out
{
background-image
:
url(https://gw.alicdn.com/tfs/TB1s0qhBHGYBuNjy0FoXXciBFXa-90-90.png)
}
.zoom
.zoom-out.disabled
{
opacity
:
.5
}
.zoom
.zoom-in
{
background-image
:
url(https://gw.alicdn.com/tfs/TB1UIgJBTtYBeNjy1XdXXXXyVXa-90-90.png)
}
.zoom
.zoom-in.disabled
{
opacity
:
.5
}
.auto-judge
:hover
.editable-title
,
.node-wrap-box
:hover
.editable-title
{
border-bottom
:
1px
dashed
#fff
}
.auto-judge
:hover
.editable-title.editing
,
.node-wrap-box
:hover
.editable-title.editing
{
text-decoration
:
none
;
border
:
1px
solid
#d9d9d9
}
.auto-judge
:hover
.editable-title
{
border-color
:
#15bc83
}
.editable-title
{
line-height
:
15px
;
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
border-bottom
:
1px
dashed
transparent
}
.editable-title
:before
{
content
:
""
;
position
:
absolute
;
top
:
0
;
left
:
0
;
bottom
:
0
;
right
:
40px
}
.editable-title
:hover
{
border-bottom
:
1px
dashed
#fff
}
.editable-title-input
{
flex
:
none
;
height
:
18px
;
padding-left
:
4px
;
text-indent
:
0
;
font-size
:
12px
;
line-height
:
18px
;
z-index
:
1
}
.editable-title-input
:hover
{
text-decoration
:
none
}
.ant-btn
{
position
:
relative
}
.node-wrap-box
{
display
:
-webkit-inline-box
;
display
:
-ms-inline-flexbox
;
display
:
inline-flex
;
-webkit-box-orient
:
vertical
;
-webkit-box-direction
:
normal
;
-ms-flex-direction
:
column
;
flex-direction
:
column
;
position
:
relative
;
width
:
220px
;
min-height
:
72px
;
-ms-flex-negative
:
0
;
flex-shrink
:
0
;
background
:
#fff
;
border-radius
:
4px
;
cursor
:
pointer
}
.node-wrap-box
:after
{
pointer-events
:
none
;
content
:
""
;
position
:
absolute
;
top
:
0
;
bottom
:
0
;
left
:
0
;
right
:
0
;
z-index
:
2
;
border-radius
:
4px
;
border
:
1px
solid
transparent
;
transition
:
all
.1s
cubic-bezier
(
.645
,
.045
,
.355
,
1
);
box-shadow
:
0
2px
5px
0
rgba
(
0
,
0
,
0
,
.1
)
}
.node-wrap-box.active
:after
,
.node-wrap-box
:active:after
,
.node-wrap-box
:hover:after
{
border
:
1px
solid
#3296fa
;
box-shadow
:
0
0
6px
0
rgba
(
50
,
150
,
250
,
.3
)
}
.node-wrap-box.active
.close
,
.node-wrap-box
:active
.close
,
.node-wrap-box
:hover
.close
{
display
:
block
}
.node-wrap-box.error
:after
{
border
:
1px
solid
#f25643
;
box-shadow
:
0
2px
5px
0
rgba
(
0
,
0
,
0
,
.1
)
}
.node-wrap-box
.title
{
position
:
relative
;
display
:
flex
;
align-items
:
center
;
padding-left
:
16px
;
padding-right
:
30px
;
width
:
100%
;
height
:
24px
;
line-height
:
24px
;
font-size
:
12px
;
color
:
#fff
;
text-align
:
left
;
background
:
#576a95
;
border-radius
:
4px
4px
0
0
}
.node-wrap-box
.title
.iconfont
{
font-size
:
12px
;
margin-right
:
5px
}
.node-wrap-box
.placeholder
{
color
:
#bfbfbf
}
.node-wrap-box
.close
{
display
:
none
;
position
:
absolute
;
right
:
10px
;
top
:
50%
;
transform
:
translateY
(
-50%
);
width
:
20px
;
height
:
20px
;
font-size
:
14px
;
color
:
#fff
;
border-radius
:
50%
;
text-align
:
center
;
line-height
:
20px
}
.node-wrap-box
.content
{
position
:
relative
;
font-size
:
14px
;
padding
:
16px
;
padding-right
:
30px
}
.node-wrap-box
.content
.text
{
overflow
:
hidden
;
text-overflow
:
ellipsis
;
display
:
-webkit-box
;
-webkit-line-clamp
:
3
;
-webkit-box-orient
:
vertical
}
.node-wrap-box
.content
.arrow
{
position
:
absolute
;
right
:
10px
;
top
:
50%
;
transform
:
translateY
(
-50%
);
width
:
20px
;
height
:
14px
;
font-size
:
14px
;
color
:
#979797
}
.start-node.node-wrap-box
.content
.text
{
display
:
block
;
white-space
:
nowrap
}
.node-wrap-box
:before
{
content
:
""
;
position
:
absolute
;
top
:
-12px
;
left
:
50%
;
-webkit-transform
:
translateX
(
-50%
);
transform
:
translateX
(
-50%
);
width
:
0
;
height
:
4px
;
border-style
:
solid
;
border-width
:
8px
6px
4px
;
border-color
:
#cacaca
transparent
transparent
;
background
:
#f5f5f7
}
.node-wrap-box.start-node
:before
{
content
:
none
}
.top-left-cover-line
{
left
:
-1px
}
.top-left-cover-line
,
.top-right-cover-line
{
position
:
absolute
;
height
:
8px
;
width
:
50%
;
background-color
:
#f5f5f7
;
top
:
-4px
}
.top-right-cover-line
{
right
:
-1px
}
.bottom-left-cover-line
{
left
:
-1px
}
.bottom-left-cover-line
,
.bottom-right-cover-line
{
position
:
absolute
;
height
:
8px
;
width
:
50%
;
background-color
:
#f5f5f7
;
bottom
:
-4px
}
.bottom-right-cover-line
{
right
:
-1px
}
.dingflow-design
{
width
:
100%
;
background-color
:
#f5f5f7
;
overflow
:
auto
;
position
:
absolute
;
bottom
:
0
;
left
:
0
;
right
:
0
;
top
:
0
}
.dingflow-design
.box-scale
{
transform
:
scale
(
1
);
display
:
inline-block
;
position
:
relative
;
width
:
100%
;
padding
:
54.5px
0
;
-webkit-box-align
:
start
;
-ms-flex-align
:
start
;
align-items
:
flex-start
;
-webkit-box-pack
:
center
;
-ms-flex-pack
:
center
;
justify-content
:
center
;
-ms-flex-wrap
:
wrap
;
flex-wrap
:
wrap
;
min-width
:
-webkit-min-content
;
min-width
:
-moz-min-content
;
min-width
:
min-content
;
background-color
:
#f5f5f7
;
transform-origin
:
50%
0px
0px
;
}
.dingflow-design
.node-wrap
{
flex-direction
:
column
;
-webkit-box-pack
:
start
;
-ms-flex-pack
:
start
;
justify-content
:
flex-start
;
-webkit-box-align
:
center
;
-ms-flex-align
:
center
;
align-items
:
center
;
-ms-flex-wrap
:
wrap
;
flex-wrap
:
wrap
;
-webkit-box-flex
:
1
;
-ms-flex-positive
:
1
;
padding
:
0
50px
;
position
:
relative
}
.dingflow-design
.branch-wrap
,
.dingflow-design
.node-wrap
{
display
:
inline-flex
;
width
:
100%
}
.dingflow-design
.branch-box-wrap
{
display
:
flex
;
-webkit-box-orient
:
vertical
;
-webkit-box-direction
:
normal
;
-ms-flex-direction
:
column
;
flex-direction
:
column
;
-ms-flex-wrap
:
wrap
;
flex-wrap
:
wrap
;
-webkit-box-align
:
center
;
-ms-flex-align
:
center
;
align-items
:
center
;
min-height
:
270px
;
width
:
100%
;
-ms-flex-negative
:
0
;
flex-shrink
:
0
}
.dingflow-design
.branch-box
{
display
:
flex
;
overflow
:
visible
;
min-height
:
180px
;
height
:
auto
;
border-bottom
:
2px
solid
#ccc
;
border-top
:
2px
solid
#ccc
;
position
:
relative
;
margin-top
:
15px
}
.dingflow-design
.branch-box
.col-box
{
background
:
#f5f5f7
}
.dingflow-design
.branch-box
.col-box
:before
{
content
:
""
;
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
z-index
:
0
;
margin
:
auto
;
width
:
2px
;
height
:
100%
;
background-color
:
#cacaca
}
.dingflow-design
.add-branch
{
border
:
none
;
outline
:
none
;
user-select
:
none
;
justify-content
:
center
;
font-size
:
12px
;
padding
:
0
10px
;
height
:
30px
;
line-height
:
30px
;
border-radius
:
15px
;
color
:
#3296fa
;
background
:
#fff
;
box-shadow
:
0
2px
4px
0
rgba
(
0
,
0
,
0
,
.1
);
position
:
absolute
;
top
:
-16px
;
left
:
50%
;
transform
:
translateX
(
-50%
);
transform-origin
:
center
center
;
cursor
:
pointer
;
z-index
:
1
;
display
:
inline-flex
;
align-items
:
center
;
-webkit-transition
:
all
.3s
cubic-bezier
(
.645
,
.045
,
.355
,
1
);
transition
:
all
.3s
cubic-bezier
(
.645
,
.045
,
.355
,
1
)
}
.dingflow-design
.add-branch
:hover
{
transform
:
translateX
(
-50%
)
scale
(
1.1
);
box-shadow
:
0
8px
16px
0
rgba
(
0
,
0
,
0
,
.1
)
}
.dingflow-design
.add-branch
:active
{
transform
:
translateX
(
-50%
);
box-shadow
:
none
}
.dingflow-design
.col-box
{
display
:
inline-flex
;
-webkit-box-orient
:
vertical
;
-webkit-box-direction
:
normal
;
flex-direction
:
column
;
-webkit-box-align
:
center
;
align-items
:
center
;
position
:
relative
}
.dingflow-design
.condition-node
{
min-height
:
220px
}
.dingflow-design
.condition-node
,
.dingflow-design
.condition-node-box
{
display
:
inline-flex
;
-webkit-box-orient
:
vertical
;
-webkit-box-direction
:
normal
;
flex-direction
:
column
;
-webkit-box-flex
:
1
}
.dingflow-design
.condition-node-box
{
padding-top
:
30px
;
padding-right
:
50px
;
padding-left
:
50px
;
-webkit-box-pack
:
center
;
justify-content
:
center
;
-webkit-box-align
:
center
;
align-items
:
center
;
flex-grow
:
1
;
position
:
relative
}
.dingflow-design
.condition-node-box
:before
{
content
:
""
;
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
margin
:
auto
;
width
:
2px
;
height
:
100%
;
background-color
:
#cacaca
}
.dingflow-design
.auto-judge
{
position
:
relative
;
width
:
220px
;
min-height
:
72px
;
background
:
#fff
;
border-radius
:
4px
;
padding
:
14px
19px
;
cursor
:
pointer
}
.dingflow-design
.auto-judge
:after
{
pointer-events
:
none
;
content
:
""
;
position
:
absolute
;
top
:
0
;
bottom
:
0
;
left
:
0
;
right
:
0
;
z-index
:
2
;
border-radius
:
4px
;
border
:
1px
solid
transparent
;
transition
:
all
.1s
cubic-bezier
(
.645
,
.045
,
.355
,
1
);
box-shadow
:
0
2px
5px
0
rgba
(
0
,
0
,
0
,
.1
)
}
.dingflow-design
.auto-judge.active
:after
,
.dingflow-design
.auto-judge
:active:after
,
.dingflow-design
.auto-judge
:hover:after
{
border
:
1px
solid
#3296fa
;
box-shadow
:
0
0
6px
0
rgba
(
50
,
150
,
250
,
.3
)
}
.dingflow-design
.auto-judge.error
:after
{
border
:
1px
solid
#f25643
;
box-shadow
:
0
2px
5px
0
rgba
(
0
,
0
,
0
,
.1
)
}
/* .dingflow-design .auto-judge .title-wrapper {
position: relative;
font-size: 12px;
color: #15bc83;
text-align: left;
height: 24px;
line-height: 24px;
width: 258px;
} */
.dingflow-design
.title-wrapper
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
position
:
relative
;
font-size
:
12px
;
border-radius
:
4px
4px
0
0
;
text-align
:
left
;
height
:
24px
;
line-height
:
24px
;
width
:
220px
;
color
:
#fff
;
padding-right
:
10px
;
padding-left
:
10px
;
}
.dingflow-design
.title-wrapper
.editable-title
{
max-width
:
120px
;
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
}
.dingflow-design
.title-wrapper
.close
{
display
:
none
;
position
:
absolute
;
right
:
10px
;
top
:
2px
;
width
:
20px
;
height
:
20px
;
font-size
:
14px
;
color
:
#fff
;
border-radius
:
50%
;
text-align
:
center
;
line-height
:
20px
;
z-index
:
2
}
.dingflow-design
.title-wrapper
:hover
.close
{
display
:
block
}
/* .dingflow-design .title-wrapper .close {
padding-right: 2px;
} */
/* .dingflow-design .title-wrapper .priority-title {
display: inline-block;
float: right;
margin-right: 10px;
color: rgba(25, 31, 37, .56)
} */
/* .dingflow-design .auto-judge .title-wrapper .editable-title {
display: inline-block;
max-width: 120px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis
}
.dingflow-design .auto-judge .title-wrapper .priority-title {
display: inline-block;
float: right;
margin-right: 10px;
color: rgba(25, 31, 37, .56)
} */
.dingflow-design
.auto-judge
.placeholder
{
color
:
#bfbfbf
}
.dingflow-design
.auto-judge
.content
{
font-size
:
14px
;
color
:
#191f25
;
text-align
:
left
;
margin-top
:
6px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
display
:
-webkit-box
;
-webkit-line-clamp
:
3
;
-webkit-box-orient
:
vertical
}
.dingflow-design
.auto-judge
.sort-left
,
.dingflow-design
.auto-judge
.sort-right
{
position
:
absolute
;
top
:
0
;
bottom
:
0
;
display
:
none
;
z-index
:
1
}
.dingflow-design
.auto-judge
.sort-left
{
left
:
0
;
border-right
:
1px
solid
#f6f6f6
}
.dingflow-design
.auto-judge
.sort-right
{
right
:
0
;
border-left
:
1px
solid
#f6f6f6
}
.dingflow-design
.auto-judge
:hover
.sort-left
,
.dingflow-design
.auto-judge
:hover
.sort-right
{
display
:
flex
;
align-items
:
center
}
.dingflow-design
.auto-judge
.sort-left
:hover
,
.dingflow-design
.auto-judge
.sort-right
:hover
{
background
:
#efefef
}
.dingflow-design
.end-node
{
border-radius
:
50%
;
font-size
:
14px
;
color
:
rgba
(
25
,
31
,
37
,
.4
);
text-align
:
left
}
.dingflow-design
.end-node
.end-node-circle
{
width
:
10px
;
height
:
10px
;
margin
:
auto
;
border-radius
:
50%
;
background
:
#dbdcdc
}
.dingflow-design
.end-node
.end-node-text
{
margin-top
:
5px
;
text-align
:
center
}
.approval-setting
{
border-radius
:
2px
;
margin
:
20px
0
;
position
:
relative
;
background
:
#fff
}
.ant-btn
{
position
:
relative
}
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
View file @
ab9ce936
...
@@ -146,9 +146,9 @@ onMounted(async () => {
...
@@ -146,9 +146,9 @@ onMounted(async () => {
processNodeTree
.
value
=
{
processNodeTree
.
value
=
{
name
:
'开始'
,
name
:
'开始'
,
type
:
NodeType
.
START_EVENT_NODE
,
type
:
NodeType
.
START_EVENT_NODE
,
id
:
'StartEvent
_1'
,
// TODO @jason:这个我们要不要 StartEvent 哈?
id
:
'StartEvent
'
,
childNode
:
{
childNode
:
{
id
:
'EndEvent
_1
'
,
id
:
'EndEvent'
,
name
:
'结束'
,
name
:
'结束'
,
type
:
NodeType
.
END_EVENT_NODE
type
:
NodeType
.
END_EVENT_NODE
}
}
...
...
src/components/SimpleProcessDesignerV2/src/consts.ts
View file @
ab9ce936
// @ts-ignore
// @ts-ignore
import
{
DictDataVO
}
from
'@/api/system/dict/types'
import
{
DictDataVO
}
from
'@/api/system/dict/types'
/**
/**
* 节点类型
* 节点类型
*/
*/
...
@@ -85,7 +86,7 @@ export enum CandidateStrategy {
...
@@ -85,7 +86,7 @@ export enum CandidateStrategy {
*/
*/
ROLE
=
10
,
ROLE
=
10
,
/**
/**
*
指定
部门成员
* 部门成员
*/
*/
DEPT_MEMBER
=
20
,
DEPT_MEMBER
=
20
,
/**
/**
...
@@ -93,6 +94,10 @@ export enum CandidateStrategy {
...
@@ -93,6 +94,10 @@ export enum CandidateStrategy {
*/
*/
DEPT_LEADER
=
21
,
DEPT_LEADER
=
21
,
/**
/**
* 连续多级部门的负责人
*/
MULTI_LEVEL_DEPT_LEADER
=
23
,
/**
* 指定岗位
* 指定岗位
*/
*/
POST
=
22
,
POST
=
22
,
...
@@ -109,6 +114,14 @@ export enum CandidateStrategy {
...
@@ -109,6 +114,14 @@ export enum CandidateStrategy {
*/
*/
START_USER
=
36
,
START_USER
=
36
,
/**
/**
* 发起人部门负责人
*/
START_USER_DEPT_LEADER
=
37
,
/**
* 发起人连续多级部门的负责人
*/
START_USER_MULTI_LEVEL_DEPT_LEADER
=
38
,
/**
* 指定用户组
* 指定用户组
*/
*/
USER_GROUP
=
40
,
USER_GROUP
=
40
,
...
@@ -280,6 +293,21 @@ NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人')
...
@@ -280,6 +293,21 @@ NODE_DEFAULT_NAME.set(NodeType.USER_TASK_NODE, '审批人')
NODE_DEFAULT_NAME
.
set
(
NodeType
.
COPY_TASK_NODE
,
'抄送人'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
COPY_TASK_NODE
,
'抄送人'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
CONDITION_NODE
,
'条件'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
CONDITION_NODE
,
'条件'
)
// 候选人策略。暂时不从字典中取。 后续可能调整。控制显示顺序
export
const
CANDIDATE_STRATEGY
:
DictDataVO
[]
=
[
{
label
:
'指定成员'
,
value
:
CandidateStrategy
.
USER
},
{
label
:
'指定角色'
,
value
:
CandidateStrategy
.
ROLE
},
{
label
:
'部门成员'
,
value
:
CandidateStrategy
.
DEPT_MEMBER
},
{
label
:
'部门负责人'
,
value
:
CandidateStrategy
.
DEPT_LEADER
},
{
label
:
'连续多级部门负责人'
,
value
:
CandidateStrategy
.
MULTI_LEVEL_DEPT_LEADER
},
{
label
:
'发起人自选'
,
value
:
CandidateStrategy
.
START_USER_SELECT
},
{
label
:
'发起人本人'
,
value
:
CandidateStrategy
.
START_USER
},
{
label
:
'发起人部门负责人'
,
value
:
CandidateStrategy
.
START_USER_DEPT_LEADER
},
{
label
:
'发起人连续部门负责人'
,
value
:
CandidateStrategy
.
START_USER_MULTI_LEVEL_DEPT_LEADER
},
{
label
:
'用户组'
,
value
:
CandidateStrategy
.
USER_GROUP
},
{
label
:
'流程表达式'
,
value
:
CandidateStrategy
.
EXPRESSION
}
]
export
const
APPROVE_METHODS
:
DictDataVO
[]
=
[
export
const
APPROVE_METHODS
:
DictDataVO
[]
=
[
{
label
:
'随机挑选一人审批'
,
value
:
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
},
{
label
:
'随机挑选一人审批'
,
value
:
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
},
{
label
:
'多人会签(按通过比例%)'
,
value
:
ApproveMethodType
.
APPROVE_BY_RATIO
},
{
label
:
'多人会签(按通过比例%)'
,
value
:
ApproveMethodType
.
APPROVE_BY_RATIO
},
...
@@ -355,3 +383,21 @@ export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [
...
@@ -355,3 +383,21 @@ export const DEFAULT_BUTTON_SETTING: ButtonSetting[] = [
{
id
:
OpsButtonType
.
ADD_SIGN
,
displayName
:
'加签'
,
enable
:
false
},
{
id
:
OpsButtonType
.
ADD_SIGN
,
displayName
:
'加签'
,
enable
:
false
},
{
id
:
OpsButtonType
.
RETURN
,
displayName
:
'回退'
,
enable
:
false
}
{
id
:
OpsButtonType
.
RETURN
,
displayName
:
'回退'
,
enable
:
false
}
]
]
export
const
MULTI_LEVEL_DEPT
:
DictDataVO
=
[
{
label
:
'第1级部门'
,
value
:
1
},
{
label
:
'第2级部门'
,
value
:
2
},
{
label
:
'第3级部门'
,
value
:
3
},
{
label
:
'第4级部门'
,
value
:
4
},
{
label
:
'第5级部门'
,
value
:
5
},
{
label
:
'第6级部门'
,
value
:
6
},
{
label
:
'第7级部门'
,
value
:
7
},
{
label
:
'第8级部门'
,
value
:
8
},
{
label
:
'第9级部门'
,
value
:
9
},
{
label
:
'第10级部门'
,
value
:
10
},
{
label
:
'第11级部门'
,
value
:
11
},
{
label
:
'第12级部门'
,
value
:
12
},
{
label
:
'第13级部门'
,
value
:
13
},
{
label
:
'第14级部门'
,
value
:
14
},
{
label
:
'第15级部门'
,
value
:
15
}
]
src/components/SimpleProcessDesignerV2/src/node.ts
View file @
ab9ce936
...
@@ -89,9 +89,16 @@ export function useFormFieldsPermission() {
...
@@ -89,9 +89,16 @@ export function useFormFieldsPermission() {
}
}
export
type
UserTaskFormType
=
{
export
type
UserTaskFormType
=
{
candidateParamArray
:
any
[]
//
candidateParamArray: any[]
candidateStrategy
:
CandidateStrategy
candidateStrategy
:
CandidateStrategy
approveMethod
:
ApproveMethodType
approveMethod
:
ApproveMethodType
roleIds
?:
number
[]
// 角色
deptIds
?:
number
[]
// 部门
deptLevel
?:
number
// 部门层级
userIds
?:
number
[]
// 用户
userGroups
?:
number
[]
// 用户组
postIds
?:
number
[]
// 岗位
expression
?:
string
// 流程表达式
approveRatio
?:
number
approveRatio
?:
number
rejectHandlerType
?:
RejectHandlerType
rejectHandlerType
?:
RejectHandlerType
returnNodeId
?:
string
returnNodeId
?:
string
...
@@ -103,8 +110,15 @@ export type UserTaskFormType = {
...
@@ -103,8 +110,15 @@ export type UserTaskFormType = {
}
}
export
type
CopyTaskFormType
=
{
export
type
CopyTaskFormType
=
{
candidateParamArray
:
any
[]
//
candidateParamArray: any[]
candidateStrategy
:
CandidateStrategy
candidateStrategy
:
CandidateStrategy
roleIds
?:
number
[]
// 角色
deptIds
?:
number
[]
// 部门
deptLevel
?:
number
// 部门层级
userIds
?:
number
[]
// 用户
userGroups
?:
number
[]
// 用户组
postIds
?:
number
[]
// 岗位
expression
?:
string
// 流程表达式
}
}
/**
/**
...
@@ -120,7 +134,7 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -120,7 +134,7 @@ export function useNodeForm(nodeType: NodeType) {
const
configForm
=
ref
<
UserTaskFormType
|
CopyTaskFormType
>
()
const
configForm
=
ref
<
UserTaskFormType
|
CopyTaskFormType
>
()
if
(
nodeType
===
NodeType
.
USER_TASK_NODE
)
{
if
(
nodeType
===
NodeType
.
USER_TASK_NODE
)
{
configForm
.
value
=
{
configForm
.
value
=
{
candidateParamArray
:
[],
//
candidateParamArray: [],
candidateStrategy
:
CandidateStrategy
.
USER
,
candidateStrategy
:
CandidateStrategy
.
USER
,
approveMethod
:
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
,
approveMethod
:
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
,
approveRatio
:
100
,
approveRatio
:
100
,
...
@@ -134,7 +148,7 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -134,7 +148,7 @@ export function useNodeForm(nodeType: NodeType) {
}
}
}
else
{
}
else
{
configForm
.
value
=
{
configForm
.
value
=
{
candidateParamArray
:
[],
//
candidateParamArray: [],
candidateStrategy
:
CandidateStrategy
.
USER
candidateStrategy
:
CandidateStrategy
.
USER
}
}
}
}
...
@@ -143,10 +157,10 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -143,10 +157,10 @@ export function useNodeForm(nodeType: NodeType) {
let
showText
=
''
let
showText
=
''
// 指定成员
// 指定成员
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
USER
)
{
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
USER
)
{
if
(
configForm
.
value
.
candidateParamArray
?
.
length
>
0
)
{
if
(
configForm
.
value
?.
userIds
!
.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
const
candidateNames
:
string
[]
=
[]
userOptions
?.
value
.
forEach
((
item
)
=>
{
userOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
configForm
.
value
?.
candidateParamArray
.
includes
(
item
.
id
))
{
if
(
configForm
.
value
?.
userIds
!
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
nickname
)
candidateNames
.
push
(
item
.
nickname
)
}
}
})
})
...
@@ -155,10 +169,10 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -155,10 +169,10 @@ export function useNodeForm(nodeType: NodeType) {
}
}
// 指定角色
// 指定角色
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
ROLE
)
{
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
ROLE
)
{
if
(
configForm
.
value
.
candidateParamArray
?
.
length
>
0
)
{
if
(
configForm
.
value
.
roleIds
!
.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
const
candidateNames
:
string
[]
=
[]
roleOptions
?.
value
.
forEach
((
item
)
=>
{
roleOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
configForm
.
value
?.
candidateParamArray
.
includes
(
item
.
id
))
{
if
(
configForm
.
value
?.
roleIds
!
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
name
)
candidateNames
.
push
(
item
.
name
)
}
}
})
})
...
@@ -168,29 +182,32 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -168,29 +182,32 @@ export function useNodeForm(nodeType: NodeType) {
// 指定部门
// 指定部门
if
(
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
DEPT_MEMBER
||
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
DEPT_MEMBER
||
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
DEPT_LEADER
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
DEPT_LEADER
||
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
MULTI_LEVEL_DEPT_LEADER
)
{
)
{
if
(
configForm
.
value
?.
candidateParamArray
?
.
length
>
0
)
{
if
(
configForm
.
value
?.
deptIds
!
.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
const
candidateNames
:
string
[]
=
[]
deptOptions
?.
value
.
forEach
((
item
)
=>
{
deptOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
configForm
.
value
?.
candidateParamArray
.
includes
(
item
.
id
))
{
if
(
configForm
.
value
?.
deptIds
!
.
includes
(
item
.
id
!
))
{
candidateNames
.
push
(
item
.
name
)
candidateNames
.
push
(
item
.
name
)
}
}
})
})
if
(
configForm
.
value
.
candidateStrategy
===
CandidateStrategy
.
DEPT_MEMBER
)
{
if
(
configForm
.
value
.
candidateStrategy
===
CandidateStrategy
.
DEPT_MEMBER
)
{
showText
=
`部门成员:
${
candidateNames
.
join
(
','
)}
`
showText
=
`部门成员:
${
candidateNames
.
join
(
','
)}
`
}
else
{
}
else
if
(
configForm
.
value
.
candidateStrategy
===
CandidateStrategy
.
DEPT_LEADER
)
{
showText
=
`部门的负责人:
${
candidateNames
.
join
(
','
)}
`
showText
=
`部门的负责人:
${
candidateNames
.
join
(
','
)}
`
}
else
{
showText
=
`多级部门的负责人:
${
candidateNames
.
join
(
','
)}
`
}
}
}
}
}
}
// 指定岗位
// 指定岗位
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
POST
)
{
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
POST
)
{
if
(
configForm
.
value
.
candidateParamArray
?
.
length
>
0
)
{
if
(
configForm
.
value
.
postIds
!
.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
const
candidateNames
:
string
[]
=
[]
postOptions
?.
value
.
forEach
((
item
)
=>
{
postOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
configForm
.
value
?.
candidateParamArray
.
includes
(
item
.
id
))
{
if
(
configForm
.
value
?.
postIds
!
.
includes
(
item
.
id
!
))
{
candidateNames
.
push
(
item
.
name
)
candidateNames
.
push
(
item
.
name
)
}
}
})
})
...
@@ -199,10 +216,10 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -199,10 +216,10 @@ export function useNodeForm(nodeType: NodeType) {
}
}
// 指定用户组
// 指定用户组
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
USER_GROUP
)
{
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
USER_GROUP
)
{
if
(
configForm
.
value
?.
candidateParamArray
?
.
length
>
0
)
{
if
(
configForm
.
value
?.
userGroups
!
.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
const
candidateNames
:
string
[]
=
[]
userGroupOptions
?.
value
.
forEach
((
item
)
=>
{
userGroupOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
configForm
.
value
?.
candidateParamArray
.
includes
(
item
.
id
))
{
if
(
configForm
.
value
?.
userGroups
!
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
name
)
candidateNames
.
push
(
item
.
name
)
}
}
})
})
...
@@ -218,16 +235,116 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -218,16 +235,116 @@ export function useNodeForm(nodeType: NodeType) {
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
START_USER
)
{
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
START_USER
)
{
showText
=
`发起人自己`
showText
=
`发起人自己`
}
}
// 发起人的部门负责人
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
START_USER_DEPT_LEADER
)
{
showText
=
`发起人的部门负责人`
}
// 发起人的部门负责人
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
START_USER_MULTI_LEVEL_DEPT_LEADER
)
{
showText
=
`发起人连续部门负责人`
}
// 流程表达式
// 流程表达式
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
EXPRESSION
)
{
if
(
configForm
.
value
?.
candidateStrategy
===
CandidateStrategy
.
EXPRESSION
)
{
if
(
configForm
.
value
.
candidateParamArray
?.
length
>
0
)
{
showText
=
`流程表达式:
${
configForm
.
value
.
expression
}
`
showText
=
`流程表达式:
${
configForm
.
value
.
candidateParamArray
[
0
]}
`
}
}
}
return
showText
return
showText
}
}
/**
* 处理候选人参数的赋值
*/
const
handleCandidateParam
=
()
=>
{
let
candidateParam
:
undefined
|
string
=
undefined
if
(
!
configForm
.
value
)
{
return
candidateParam
}
switch
(
configForm
.
value
.
candidateStrategy
)
{
case
CandidateStrategy
.
USER
:
candidateParam
=
configForm
.
value
.
userIds
!
.
join
(
','
)
break
case
CandidateStrategy
.
ROLE
:
candidateParam
=
configForm
.
value
.
roleIds
!
.
join
(
','
)
break
case
CandidateStrategy
.
POST
:
candidateParam
=
configForm
.
value
.
postIds
!
.
join
(
','
)
break
case
CandidateStrategy
.
USER_GROUP
:
candidateParam
=
configForm
.
value
.
userGroups
!
.
join
(
','
)
break
case
CandidateStrategy
.
EXPRESSION
:
candidateParam
=
configForm
.
value
.
expression
!
break
case
CandidateStrategy
.
DEPT_MEMBER
:
case
CandidateStrategy
.
DEPT_LEADER
:
candidateParam
=
configForm
.
value
.
deptIds
!
.
join
(
','
)
break
// 发起人部门负责人
case
CandidateStrategy
.
START_USER_DEPT_LEADER
:
case
CandidateStrategy
.
START_USER_MULTI_LEVEL_DEPT_LEADER
:
candidateParam
=
configForm
.
value
.
deptLevel
+
''
break
// 指定连续多级部门的负责人
case
CandidateStrategy
.
MULTI_LEVEL_DEPT_LEADER
:
{
// TODO 是否允许选多个部门
const
deptIds
=
configForm
.
value
.
deptIds
!
.
join
(
','
)
candidateParam
=
deptIds
.
concat
(
','
+
configForm
.
value
.
deptLevel
+
''
)
break
}
default
:
break
}
return
candidateParam
}
/**
* 解析候选人参数
*/
const
parseCandidateParam
=
(
candidateStrategy
:
CandidateStrategy
,
candidateParam
:
string
|
undefined
)
=>
{
if
(
!
configForm
.
value
||
!
candidateParam
)
{
return
}
switch
(
candidateStrategy
)
{
case
CandidateStrategy
.
USER
:
{
configForm
.
value
.
userIds
=
candidateParam
.
split
(
','
).
map
((
item
)
=>
+
item
)
break
}
case
CandidateStrategy
.
ROLE
:
configForm
.
value
.
roleIds
=
candidateParam
.
split
(
','
).
map
((
item
)
=>
+
item
)
break
case
CandidateStrategy
.
POST
:
configForm
.
value
.
postIds
=
candidateParam
.
split
(
','
).
map
((
item
)
=>
+
item
)
break
case
CandidateStrategy
.
USER_GROUP
:
configForm
.
value
.
userGroups
=
candidateParam
.
split
(
','
).
map
((
item
)
=>
+
item
)
break
case
CandidateStrategy
.
EXPRESSION
:
configForm
.
value
.
expression
=
candidateParam
break
case
CandidateStrategy
.
DEPT_MEMBER
:
case
CandidateStrategy
.
DEPT_LEADER
:
configForm
.
value
.
deptIds
=
candidateParam
.
split
(
','
).
map
((
item
)
=>
+
item
)
break
// 发起人部门负责人
case
CandidateStrategy
.
START_USER_DEPT_LEADER
:
case
CandidateStrategy
.
START_USER_MULTI_LEVEL_DEPT_LEADER
:
configForm
.
value
.
deptLevel
=
+
candidateParam
break
// 指定连续多级部门的负责人
case
CandidateStrategy
.
MULTI_LEVEL_DEPT_LEADER
:
{
// 暂时只能选一个部门
const
paramArray
=
candidateParam
.
split
(
','
)
configForm
.
value
.
deptIds
=
[
+
paramArray
[
0
]]
configForm
.
value
.
deptLevel
=
+
paramArray
[
1
]
break
}
default
:
break
}
}
return
{
return
{
configForm
,
configForm
,
roleOptions
,
roleOptions
,
...
@@ -235,6 +352,8 @@ export function useNodeForm(nodeType: NodeType) {
...
@@ -235,6 +352,8 @@ export function useNodeForm(nodeType: NodeType) {
userOptions
,
userOptions
,
userGroupOptions
,
userGroupOptions
,
deptTreeOptions
,
deptTreeOptions
,
handleCandidateParam
,
parseCandidateParam
,
getShowText
getShowText
}
}
}
}
...
...
src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue
View file @
ab9ce936
...
@@ -46,14 +46,9 @@
...
@@ -46,14 +46,9 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy == CandidateStrategy.ROLE"
v-if=
"configForm.candidateStrategy == CandidateStrategy.ROLE"
label=
"指定角色"
label=
"指定角色"
prop=
"
candidateParamArray
"
prop=
"
roleIds
"
>
>
<el-select
<el-select
v-model=
"configForm.roleIds"
clearable
multiple
style=
"width: 100%"
>
v-model=
"configForm.candidateParamArray"
clearable
multiple
style=
"width: 100%"
>
<el-option
<el-option
v-for=
"item in roleOptions"
v-for=
"item in roleOptions"
:key=
"item.id"
:key=
"item.id"
...
@@ -68,12 +63,12 @@
...
@@ -68,12 +63,12 @@
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER
"
"
label=
"指定部门"
label=
"指定部门"
prop=
"
candidateParamArray
"
prop=
"
deptIds
"
span=
"24"
span=
"24"
>
>
<el-tree-select
<el-tree-select
ref=
"treeRef"
ref=
"treeRef"
v-model=
"configForm.
candidateParamArray
"
v-model=
"configForm.
deptIds
"
:data=
"deptTreeOptions"
:data=
"deptTreeOptions"
:props=
"defaultProps"
:props=
"defaultProps"
empty-text=
"加载中,请稍后"
empty-text=
"加载中,请稍后"
...
@@ -86,15 +81,10 @@
...
@@ -86,15 +81,10 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy == CandidateStrategy.POST"
v-if=
"configForm.candidateStrategy == CandidateStrategy.POST"
label=
"指定岗位"
label=
"指定岗位"
prop=
"
candidateParamArray
"
prop=
"
postIds
"
span=
"24"
span=
"24"
>
>
<el-select
<el-select
v-model=
"configForm.postIds"
clearable
multiple
style=
"width: 100%"
>
v-model=
"configForm.candidateParamArray"
clearable
multiple
style=
"width: 100%"
>
<el-option
<el-option
v-for=
"item in postOptions"
v-for=
"item in postOptions"
:key=
"item.id"
:key=
"item.id"
...
@@ -106,15 +96,10 @@
...
@@ -106,15 +96,10 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy == CandidateStrategy.USER"
v-if=
"configForm.candidateStrategy == CandidateStrategy.USER"
label=
"指定用户"
label=
"指定用户"
prop=
"
candidateParamArray
"
prop=
"
userIds
"
span=
"24"
span=
"24"
>
>
<el-select
<el-select
v-model=
"configForm.userIds"
clearable
multiple
style=
"width: 100%"
>
v-model=
"configForm.candidateParamArray"
clearable
multiple
style=
"width: 100%"
>
<el-option
<el-option
v-for=
"item in userOptions"
v-for=
"item in userOptions"
:key=
"item.id"
:key=
"item.id"
...
@@ -126,14 +111,9 @@
...
@@ -126,14 +111,9 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
v-if=
"configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
label=
"指定用户组"
label=
"指定用户组"
prop=
"
candidateParamArray
"
prop=
"
userGroups
"
>
>
<el-select
<el-select
v-model=
"configForm.userGroups"
clearable
multiple
style=
"width: 100%"
>
v-model=
"configForm.candidateParamArray"
clearable
multiple
style=
"width: 100%"
>
<el-option
<el-option
v-for=
"item in userGroupOptions"
v-for=
"item in userGroupOptions"
:key=
"item.id"
:key=
"item.id"
...
@@ -146,11 +126,11 @@
...
@@ -146,11 +126,11 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
v-if=
"configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
label=
"流程表达式"
label=
"流程表达式"
prop=
"
candidateParamArray
"
prop=
"
expression
"
>
>
<el-input
<el-input
type=
"textarea"
type=
"textarea"
v-model=
"configForm.
candidateParamArray[0]
"
v-model=
"configForm.
expression
"
clearable
clearable
style=
"width: 100%"
style=
"width: 100%"
/>
/>
...
@@ -200,7 +180,7 @@
...
@@ -200,7 +180,7 @@
</el-drawer>
</el-drawer>
</template>
</template>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
SimpleFlowNode
,
CandidateStrategy
,
NodeType
}
from
'../consts'
import
{
SimpleFlowNode
,
CandidateStrategy
,
NodeType
,
CANDIDATE_STRATEGY
}
from
'../consts'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
import
{
useWatchNode
,
useWatchNode
,
...
@@ -235,7 +215,12 @@ const formRef = ref() // 表单 Ref
...
@@ -235,7 +215,12 @@ const formRef = ref() // 表单 Ref
// 表单校验规则
// 表单校验规则
const
formRules
=
reactive
({
const
formRules
=
reactive
({
candidateStrategy
:
[{
required
:
true
,
message
:
'抄送人设置不能为空'
,
trigger
:
'change'
}],
candidateStrategy
:
[{
required
:
true
,
message
:
'抄送人设置不能为空'
,
trigger
:
'change'
}],
candidateParamArray
:
[{
required
:
true
,
message
:
'选项不能为空'
,
trigger
:
'blur'
}]
userIds
:
[{
required
:
true
,
message
:
'用户不能为空'
,
trigger
:
'change'
}],
roleIds
:
[{
required
:
true
,
message
:
'角色不能为空'
,
trigger
:
'change'
}],
deptIds
:
[{
required
:
true
,
message
:
'部门不能为空'
,
trigger
:
'change'
}],
userGroups
:
[{
required
:
true
,
message
:
'用户组不能为空'
,
trigger
:
'change'
}],
postIds
:
[{
required
:
true
,
message
:
'岗位不能为空'
,
trigger
:
'change'
}],
expression
:
[{
required
:
true
,
message
:
'流程表达式不能为空'
,
trigger
:
'blur'
}]
})
})
const
{
const
{
...
@@ -245,12 +230,14 @@ const {
...
@@ -245,12 +230,14 @@ const {
userOptions
,
userOptions
,
userGroupOptions
,
userGroupOptions
,
deptTreeOptions
,
deptTreeOptions
,
getShowText
getShowText
,
handleCandidateParam
,
parseCandidateParam
}
=
useNodeForm
(
NodeType
.
COPY_TASK_NODE
)
}
=
useNodeForm
(
NodeType
.
COPY_TASK_NODE
)
const
configForm
=
tempConfigForm
as
Ref
<
CopyTaskFormType
>
const
configForm
=
tempConfigForm
as
Ref
<
CopyTaskFormType
>
// 抄送人策略, 去掉发起人自选 和 发起人自己
// 抄送人策略, 去掉发起人自选 和 发起人自己
const
copyUserStrategies
=
computed
(()
=>
{
const
copyUserStrategies
=
computed
(()
=>
{
return
getIntDictOptions
(
DICT_TYPE
.
BPM_TASK_CANDIDATE_STRATEGY
)
.
filter
(
return
CANDIDATE_STRATEGY
.
filter
(
(
item
)
=>
(
item
)
=>
item
.
value
!==
CandidateStrategy
.
START_USER_SELECT
&&
item
.
value
!==
CandidateStrategy
.
START_USER_SELECT
&&
item
.
value
!==
CandidateStrategy
.
START_USER
item
.
value
!==
CandidateStrategy
.
START_USER
...
@@ -258,7 +245,12 @@ const copyUserStrategies = computed(() => {
...
@@ -258,7 +245,12 @@ const copyUserStrategies = computed(() => {
})
})
// 改变抄送人设置策略
// 改变抄送人设置策略
const
changeCandidateStrategy
=
()
=>
{
const
changeCandidateStrategy
=
()
=>
{
configForm
.
value
.
candidateParamArray
=
[]
configForm
.
value
.
userIds
=
[]
configForm
.
value
.
deptIds
=
[]
configForm
.
value
.
roleIds
=
[]
configForm
.
value
.
postIds
=
[]
configForm
.
value
.
userGroups
=
[]
configForm
.
value
.
deptLevel
=
1
}
}
// 保存配置
// 保存配置
const
saveConfig
=
async
()
=>
{
const
saveConfig
=
async
()
=>
{
...
@@ -269,7 +261,7 @@ const saveConfig = async () => {
...
@@ -269,7 +261,7 @@ const saveConfig = async () => {
const
showText
=
getShowText
()
const
showText
=
getShowText
()
if
(
!
showText
)
return
false
if
(
!
showText
)
return
false
currentNode
.
value
.
name
=
nodeName
.
value
!
currentNode
.
value
.
name
=
nodeName
.
value
!
currentNode
.
value
.
candidateParam
=
configForm
.
value
.
candidateParamArray
?.
join
(
','
)
handleCandidateParam
(
)
currentNode
.
value
.
candidateStrategy
=
configForm
.
value
.
candidateStrategy
currentNode
.
value
.
candidateStrategy
=
configForm
.
value
.
candidateStrategy
currentNode
.
value
.
showText
=
showText
currentNode
.
value
.
showText
=
showText
currentNode
.
value
.
fieldsPermission
=
fieldsPermissionConfig
.
value
currentNode
.
value
.
fieldsPermission
=
fieldsPermissionConfig
.
value
...
@@ -281,14 +273,7 @@ const showCopyTaskNodeConfig = (node: SimpleFlowNode) => {
...
@@ -281,14 +273,7 @@ const showCopyTaskNodeConfig = (node: SimpleFlowNode) => {
nodeName
.
value
=
node
.
name
nodeName
.
value
=
node
.
name
// 抄送人设置
// 抄送人设置
configForm
.
value
.
candidateStrategy
=
node
.
candidateStrategy
!
configForm
.
value
.
candidateStrategy
=
node
.
candidateStrategy
!
const
strCandidateParam
=
node
?.
candidateParam
parseCandidateParam
(
node
.
candidateStrategy
!
,
node
?.
candidateParam
)
if
(
node
.
candidateStrategy
===
CandidateStrategy
.
EXPRESSION
)
{
configForm
.
value
.
candidateParamArray
[
0
]
=
strCandidateParam
}
else
{
if
(
strCandidateParam
)
{
configForm
.
value
.
candidateParamArray
=
strCandidateParam
.
split
(
','
).
map
((
item
)
=>
+
item
)
}
}
// 表单字段权限
// 表单字段权限
getNodeConfigFormFields
(
node
.
fieldsPermission
)
getNodeConfigFormFields
(
node
.
fieldsPermission
)
}
}
...
...
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
View file @
ab9ce936
...
@@ -34,7 +34,7 @@
...
@@ -34,7 +34,7 @@
@
change=
"changeCandidateStrategy"
@
change=
"changeCandidateStrategy"
>
>
<el-radio
<el-radio
v-for=
"(dict, index) in
getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)
"
v-for=
"(dict, index) in
CANDIDATE_STRATEGY
"
:key=
"index"
:key=
"index"
:value=
"dict.value"
:value=
"dict.value"
:label=
"dict.value"
:label=
"dict.value"
...
@@ -47,14 +47,9 @@
...
@@ -47,14 +47,9 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy == CandidateStrategy.ROLE"
v-if=
"configForm.candidateStrategy == CandidateStrategy.ROLE"
label=
"指定角色"
label=
"指定角色"
prop=
"
candidateParamArray
"
prop=
"
roleIds
"
>
>
<el-select
<el-select
v-model=
"configForm.roleIds"
clearable
multiple
style=
"width: 100%"
>
v-model=
"configForm.candidateParamArray"
clearable
multiple
style=
"width: 100%"
>
<el-option
<el-option
v-for=
"item in roleOptions"
v-for=
"item in roleOptions"
:key=
"item.id"
:key=
"item.id"
...
@@ -66,15 +61,16 @@
...
@@ -66,15 +61,16 @@
<el-form-item
<el-form-item
v-if=
"
v-if=
"
configForm.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
configForm.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER
configForm.candidateStrategy == CandidateStrategy.DEPT_LEADER ||
configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER
"
"
label=
"指定部门"
label=
"指定部门"
prop=
"
candidateParamArray
"
prop=
"
deptIds
"
span=
"24"
span=
"24"
>
>
<el-tree-select
<el-tree-select
ref=
"treeRef"
ref=
"treeRef"
v-model=
"configForm.
candidateParamArray
"
v-model=
"configForm.
deptIds
"
:data=
"deptTreeOptions"
:data=
"deptTreeOptions"
:props=
"defaultProps"
:props=
"defaultProps"
empty-text=
"加载中,请稍后"
empty-text=
"加载中,请稍后"
...
@@ -85,17 +81,31 @@
...
@@ -85,17 +81,31 @@
/>
/>
</el-form-item>
</el-form-item>
<el-form-item
<el-form-item
v-if=
"
configForm.candidateStrategy == CandidateStrategy.MULTI_LEVEL_DEPT_LEADER ||
configForm.candidateStrategy == CandidateStrategy.START_USER_DEPT_LEADER ||
configForm.candidateStrategy == CandidateStrategy.START_USER_MULTI_LEVEL_DEPT_LEADER
"
:label=
"deptLevelLabel!"
prop=
"deptLevel"
span=
"24"
>
<el-select
v-model=
"configForm.deptLevel"
clearable
>
<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=
"configForm.candidateStrategy == CandidateStrategy.POST"
v-if=
"configForm.candidateStrategy == CandidateStrategy.POST"
label=
"指定岗位"
label=
"指定岗位"
prop=
"
candidateParamArray
"
prop=
"
postIds
"
span=
"24"
span=
"24"
>
>
<el-select
<el-select
v-model=
"configForm.postIds"
clearable
multiple
style=
"width: 100%"
>
v-model=
"configForm.candidateParamArray"
clearable
multiple
style=
"width: 100%"
>
<el-option
<el-option
v-for=
"item in postOptions"
v-for=
"item in postOptions"
:key=
"item.id"
:key=
"item.id"
...
@@ -107,11 +117,11 @@
...
@@ -107,11 +117,11 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy == CandidateStrategy.USER"
v-if=
"configForm.candidateStrategy == CandidateStrategy.USER"
label=
"指定用户"
label=
"指定用户"
prop=
"
candidateParamArray
"
prop=
"
userIds
"
span=
"24"
span=
"24"
>
>
<el-select
<el-select
v-model=
"configForm.
candidateParamArray
"
v-model=
"configForm.
userIds
"
clearable
clearable
multiple
multiple
style=
"width: 100%"
style=
"width: 100%"
...
@@ -128,14 +138,9 @@
...
@@ -128,14 +138,9 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
v-if=
"configForm.candidateStrategy === CandidateStrategy.USER_GROUP"
label=
"指定用户组"
label=
"指定用户组"
prop=
"
candidateParamArray
"
prop=
"
userGroups
"
>
>
<el-select
<el-select
v-model=
"configForm.userGroups"
clearable
multiple
style=
"width: 100%"
>
v-model=
"configForm.candidateParamArray"
clearable
multiple
style=
"width: 100%"
>
<el-option
<el-option
v-for=
"item in userGroupOptions"
v-for=
"item in userGroupOptions"
:key=
"item.id"
:key=
"item.id"
...
@@ -147,11 +152,11 @@
...
@@ -147,11 +152,11 @@
<el-form-item
<el-form-item
v-if=
"configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
v-if=
"configForm.candidateStrategy === CandidateStrategy.EXPRESSION"
label=
"流程表达式"
label=
"流程表达式"
prop=
"
candidateParamArray
"
prop=
"
expression
"
>
>
<el-input
<el-input
type=
"textarea"
type=
"textarea"
v-model=
"configForm.
candidateParamArray[0]
"
v-model=
"configForm.
expression
"
clearable
clearable
style=
"width: 100%"
style=
"width: 100%"
/>
/>
...
@@ -364,9 +369,11 @@ import {
...
@@ -364,9 +369,11 @@ import {
REJECT_HANDLER_TYPES
,
REJECT_HANDLER_TYPES
,
DEFAULT_BUTTON_SETTING
,
DEFAULT_BUTTON_SETTING
,
OPERATION_BUTTON_NAME
,
OPERATION_BUTTON_NAME
,
ButtonSetting
ButtonSetting
,
MULTI_LEVEL_DEPT
,
CANDIDATE_STRATEGY
}
from
'../consts'
}
from
'../consts'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
import
{
useWatchNode
,
useWatchNode
,
useNodeName
,
useNodeName
,
...
@@ -390,6 +397,15 @@ const props = defineProps({
...
@@ -390,6 +397,15 @@ const props = defineProps({
const
emits
=
defineEmits
<
{
const
emits
=
defineEmits
<
{
'find:returnTaskNodes'
:
[
nodeList
:
SimpleFlowNode
[]]
'find:returnTaskNodes'
:
[
nodeList
:
SimpleFlowNode
[]]
}
>
()
}
>
()
const
deptLevelLabel
=
computed
(()
=>
{
let
label
=
'部门负责人来源'
if
(
configForm
.
value
.
candidateStrategy
==
CandidateStrategy
.
MULTI_LEVEL_DEPT_LEADER
)
{
label
=
label
+
'(指定部门向上)'
}
else
{
label
=
label
+
'(发起人部门向上)'
}
return
label
})
// 监控节点的变化
// 监控节点的变化
const
currentNode
=
useWatchNode
(
props
)
const
currentNode
=
useWatchNode
(
props
)
// 抽屉配置
// 抽屉配置
...
@@ -409,7 +425,12 @@ const formRef = ref() // 表单 Ref
...
@@ -409,7 +425,12 @@ const formRef = ref() // 表单 Ref
// 表单校验规则
// 表单校验规则
const
formRules
=
reactive
({
const
formRules
=
reactive
({
candidateStrategy
:
[{
required
:
true
,
message
:
'审批人设置不能为空'
,
trigger
:
'change'
}],
candidateStrategy
:
[{
required
:
true
,
message
:
'审批人设置不能为空'
,
trigger
:
'change'
}],
candidateParamArray
:
[{
required
:
true
,
message
:
'该选项不能为空'
,
trigger
:
'change'
}],
userIds
:
[{
required
:
true
,
message
:
'用户不能为空'
,
trigger
:
'change'
}],
roleIds
:
[{
required
:
true
,
message
:
'角色不能为空'
,
trigger
:
'change'
}],
deptIds
:
[{
required
:
true
,
message
:
'部门不能为空'
,
trigger
:
'change'
}],
userGroups
:
[{
required
:
true
,
message
:
'用户组不能为空'
,
trigger
:
'change'
}],
postIds
:
[{
required
:
true
,
message
:
'岗位不能为空'
,
trigger
:
'change'
}],
expression
:
[{
required
:
true
,
message
:
'流程表达式不能为空'
,
trigger
:
'blur'
}],
approveMethod
:
[{
required
:
true
,
message
:
'多人审批方式不能为空'
,
trigger
:
'change'
}],
approveMethod
:
[{
required
:
true
,
message
:
'多人审批方式不能为空'
,
trigger
:
'change'
}],
approveRatio
:
[{
required
:
true
,
message
:
'通过比例不能为空'
,
trigger
:
'blur'
}],
approveRatio
:
[{
required
:
true
,
message
:
'通过比例不能为空'
,
trigger
:
'blur'
}],
returnNodeId
:
[{
required
:
true
,
message
:
'驳回节点不能为空'
,
trigger
:
'change'
}],
returnNodeId
:
[{
required
:
true
,
message
:
'驳回节点不能为空'
,
trigger
:
'change'
}],
...
@@ -426,6 +447,8 @@ const {
...
@@ -426,6 +447,8 @@ const {
userOptions
,
userOptions
,
userGroupOptions
,
userGroupOptions
,
deptTreeOptions
,
deptTreeOptions
,
handleCandidateParam
,
parseCandidateParam
,
getShowText
getShowText
}
=
useNodeForm
(
NodeType
.
USER_TASK_NODE
)
}
=
useNodeForm
(
NodeType
.
USER_TASK_NODE
)
const
configForm
=
tempConfigForm
as
Ref
<
UserTaskFormType
>
const
configForm
=
tempConfigForm
as
Ref
<
UserTaskFormType
>
...
@@ -433,7 +456,12 @@ const configForm = tempConfigForm as Ref<UserTaskFormType>
...
@@ -433,7 +456,12 @@ const configForm = tempConfigForm as Ref<UserTaskFormType>
const
notAllowedMultiApprovers
=
ref
(
false
)
const
notAllowedMultiApprovers
=
ref
(
false
)
// 改变审批人设置策略
// 改变审批人设置策略
const
changeCandidateStrategy
=
()
=>
{
const
changeCandidateStrategy
=
()
=>
{
configForm
.
value
.
candidateParamArray
=
[]
configForm
.
value
.
userIds
=
[]
configForm
.
value
.
deptIds
=
[]
configForm
.
value
.
roleIds
=
[]
configForm
.
value
.
postIds
=
[]
configForm
.
value
.
userGroups
=
[]
configForm
.
value
.
deptLevel
=
1
configForm
.
value
.
approveMethod
=
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
configForm
.
value
.
approveMethod
=
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
if
(
if
(
configForm
.
value
.
candidateStrategy
===
CandidateStrategy
.
START_USER
||
configForm
.
value
.
candidateStrategy
===
CandidateStrategy
.
START_USER
||
...
@@ -447,7 +475,8 @@ const changeCandidateStrategy = () => {
...
@@ -447,7 +475,8 @@ const changeCandidateStrategy = () => {
// 改变审批候选人
// 改变审批候选人
const
changedCandidateUsers
=
()
=>
{
const
changedCandidateUsers
=
()
=>
{
if
(
if
(
configForm
.
value
.
candidateParamArray
?.
length
<=
1
&&
configForm
.
value
.
userIds
&&
configForm
.
value
.
userIds
?.
length
<=
1
&&
configForm
.
value
.
candidateStrategy
===
CandidateStrategy
.
USER
configForm
.
value
.
candidateStrategy
===
CandidateStrategy
.
USER
)
{
)
{
configForm
.
value
.
approveMethod
=
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
configForm
.
value
.
approveMethod
=
ApproveMethodType
.
RRANDOM_SELECT_ONE_APPROVE
...
@@ -488,7 +517,8 @@ const saveConfig = async () => {
...
@@ -488,7 +517,8 @@ const saveConfig = async () => {
if
(
!
showText
)
return
false
if
(
!
showText
)
return
false
currentNode
.
value
.
name
=
nodeName
.
value
!
currentNode
.
value
.
name
=
nodeName
.
value
!
currentNode
.
value
.
candidateStrategy
=
configForm
.
value
.
candidateStrategy
currentNode
.
value
.
candidateStrategy
=
configForm
.
value
.
candidateStrategy
currentNode
.
value
.
candidateParam
=
configForm
.
value
.
candidateParamArray
?.
join
(
','
)
// 处理 candidateParam 参数
currentNode
.
value
.
candidateParam
=
handleCandidateParam
()
// 设置审批方式
// 设置审批方式
currentNode
.
value
.
approveMethod
=
configForm
.
value
.
approveMethod
currentNode
.
value
.
approveMethod
=
configForm
.
value
.
approveMethod
if
(
configForm
.
value
.
approveMethod
===
ApproveMethodType
.
APPROVE_BY_RATIO
)
{
if
(
configForm
.
value
.
approveMethod
===
ApproveMethodType
.
APPROVE_BY_RATIO
)
{
...
@@ -521,19 +551,9 @@ const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
...
@@ -521,19 +551,9 @@ const showUserTaskNodeConfig = (node: SimpleFlowNode) => {
nodeName
.
value
=
node
.
name
nodeName
.
value
=
node
.
name
//1.1 审批人设置
//1.1 审批人设置
configForm
.
value
.
candidateStrategy
=
node
.
candidateStrategy
!
configForm
.
value
.
candidateStrategy
=
node
.
candidateStrategy
!
const
strCandidateParam
=
node
?.
candidateParam
// 解析候选人参数
if
(
node
.
candidateStrategy
===
CandidateStrategy
.
EXPRESSION
)
{
parseCandidateParam
(
node
.
candidateStrategy
!
,
node
?.
candidateParam
)
configForm
.
value
.
candidateParamArray
[
0
]
=
strCandidateParam
if
(
configForm
.
value
.
deptIds
&&
configForm
.
value
.
deptIds
.
length
>
1
)
{
}
else
{
if
(
strCandidateParam
)
{
configForm
.
value
.
candidateParamArray
=
strCandidateParam
.
split
(
','
).
map
((
item
)
=>
+
item
)
}
}
if
(
(
configForm
.
value
.
candidateParamArray
?.
length
<=
1
&&
node
.
candidateStrategy
===
CandidateStrategy
.
USER
)
||
node
.
candidateStrategy
===
CandidateStrategy
.
START_USER
)
{
notAllowedMultiApprovers
.
value
=
true
notAllowedMultiApprovers
.
value
=
true
}
else
{
}
else
{
notAllowedMultiApprovers
.
value
=
false
notAllowedMultiApprovers
.
value
=
false
...
...
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