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
ee895d07
authored
Apr 27, 2024
by
jason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
仿钉钉流程设计器-抄送节点改造.
parent
676ed6bd
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
499 additions
and
36 deletions
+499
-36
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
+21
-6
src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue
+5
-1
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
+6
-0
src/components/SimpleProcessDesignerV2/src/consts.ts
+8
-1
src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue
+302
-0
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
+5
-5
src/components/SimpleProcessDesignerV2/src/nodes/CopyTaskNode.vue
+103
-0
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
+10
-19
src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss
+14
-4
src/views/bpm/simpleWorkflow/index.vue
+25
-0
No files found.
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
View file @
ee895d07
...
...
@@ -9,12 +9,12 @@
</div>
<div
class=
"handler-item-text"
>
审批人
</div>
</div>
<
!--
<div
class=
"handler-item"
@
click=
"addNode(NodeType.CONDITION
_NODE)"
>
<div
class=
"handler-item-icon"
>
<span
class=
"iconfont icon-size icon-
exclusive
"
></span>
<
div
class=
"handler-item"
@
click=
"addNode(NodeType.COPY_TASK
_NODE)"
>
<div
class=
"handler-item-icon
copy
"
>
<span
class=
"iconfont icon-size icon-
copy
"
></span>
</div>
<div
class=
"handler-item-text"
>
条件分支
</div>
</div>
-->
<div
class=
"handler-item-text"
>
抄送
</div>
</div>
</div>
<template
#
reference
>
<div
class=
"add-icon"
><Icon
icon=
"ep:plus"
/></div>
...
...
@@ -25,7 +25,7 @@
</template>
<
script
setup
lang=
"ts"
>
import
{
SimpleFlowNode
,
NodeType
,
NODE_DEFAULT_NAME
,
CandidateStrategy
,
APPROVE_METHODS
}
from
'./consts'
import
{
SimpleFlowNode
,
NodeType
,
NODE_DEFAULT_NAME
,
CandidateStrategy
}
from
'./consts'
import
{
generateUUID
}
from
'@/utils'
defineOptions
({
name
:
'NodeHandler'
...
...
@@ -64,6 +64,21 @@ const addNode = (type: number) => {
}
emits
(
'update:childNode'
,
data
)
}
if
(
type
===
NodeType
.
COPY_TASK_NODE
)
{
const
data
:
SimpleFlowNode
=
{
id
:
generateUUID
(),
name
:
NODE_DEFAULT_NAME
.
get
(
NodeType
.
COPY_TASK_NODE
)
as
string
,
showText
:
''
,
type
:
NodeType
.
COPY_TASK_NODE
,
// 审批节点配置
attributes
:
{
candidateStrategy
:
CandidateStrategy
.
USER
,
candidateParam
:
undefined
},
childNode
:
props
.
childNode
}
emits
(
'update:childNode'
,
data
)
}
}
</
script
>
...
...
src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue
View file @
ee895d07
...
...
@@ -5,7 +5,10 @@
<UserTaskNode
v-if=
"currentNode && currentNode.type === NodeType.USER_TASK_NODE"
:flow-node =
"currentNode"
@
update:model-value=
"handleModelValueUpdate"
/>
<!-- 抄送节点 -->
<CopyTaskNode
v-if=
"currentNode && currentNode.type === NodeType.COPY_TASK_NODE"
:flow-node =
"currentNode"
@
update:model-value=
"handleModelValueUpdate"
/>
<!-- 递归显示孩子节点 -->
<ProcessNodeTree
v-if=
"currentNode && currentNode.childNode"
v-model:flow-node=
"currentNode.childNode"
/>
...
...
@@ -16,6 +19,7 @@
import
StartEventNode
from
'./nodes/StartEventNode.vue'
;
import
EndEventNode
from
'./nodes/EndEventNode.vue'
;
import
UserTaskNode
from
'./nodes/UserTaskNode.vue'
;
import
CopyTaskNode
from
'./nodes/CopyTaskNode.vue'
;
import
{
SimpleFlowNode
,
NodeType
}
from
'./consts'
;
defineOptions
({
name
:
'ProcessNodeTree'
...
...
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
View file @
ee895d07
...
...
@@ -102,6 +102,12 @@ const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNo
}
validateNode
(
node
.
childNode
,
errorNodes
)
}
if
(
type
===
NodeType
.
COPY_TASK_NODE
)
{
if
(
!
showText
)
{
errorNodes
.
push
(
node
)
}
validateNode
(
node
.
childNode
,
errorNodes
)
}
if
(
type
===
NodeType
.
CONDITION_NODE
)
{
if
(
!
showText
)
{
errorNodes
.
push
(
node
)
...
...
src/components/SimpleProcessDesignerV2/src/consts.ts
View file @
ee895d07
...
...
@@ -15,6 +15,11 @@ export enum NodeType {
* 审批人节点
*/
USER_TASK_NODE
=
1
,
/**
* 抄送人节点
*/
COPY_TASK_NODE
=
2
,
/**
* 条件节点
...
...
@@ -92,11 +97,13 @@ export type SimpleFlowNode = {
}
export
const
NODE_DEFAULT_TEXT
=
new
Map
<
number
,
string
>
()
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
USER_TASK_NODE
,
'请配置该节点'
)
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
USER_TASK_NODE
,
'请配置审批人'
)
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
COPY_TASK_NODE
,
'请配置抄送人'
)
NODE_DEFAULT_TEXT
.
set
(
NodeType
.
CONDITION_NODE
,
'请设置条件'
)
export
const
NODE_DEFAULT_NAME
=
new
Map
<
number
,
string
>
()
NODE_DEFAULT_NAME
.
set
(
NodeType
.
USER_TASK_NODE
,
'审批人'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
COPY_TASK_NODE
,
'抄送人'
)
NODE_DEFAULT_NAME
.
set
(
NodeType
.
CONDITION_NODE
,
'条件'
)
...
...
src/components/SimpleProcessDesignerV2/src/nodes-config/CopyTaskNodeConfig.vue
0 → 100644
View file @
ee895d07
<
template
>
<el-drawer
:append-to-body=
"true"
v-model=
"settingVisible"
:show-close=
"false"
:size=
"550"
:before-close=
"saveConfig"
class=
"justify-start"
>
<template
#
header
>
<div
class=
"w-full flex flex-col"
>
<div
class=
"mb-2 text-size-2xl"
>
{{
currentNode
.
name
}}
</div>
<el-divider
/>
</div>
</
template
>
<el-tabs
type=
"border-card"
>
<el-tab-pane
label=
"抄送人"
>
<div>
<el-form
label-position=
"top"
>
<el-form-item
label=
"抄送人设置"
prop=
"candidateStrategy"
>
<el-radio-group
v-model=
"currentNode.attributes.candidateStrategy"
@
change=
"changeCandidateStrategy"
>
<el-radio
v-for=
"(dict, index) in copyUserStrategies"
:key=
"index"
:value=
"dict.value"
:label=
"dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"currentNode.attributes.candidateStrategy == CandidateStrategy.ROLE"
label=
"指定角色"
prop=
"candidateParam"
>
<el-select
v-model=
"candidateParamArray"
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=
"
currentNode.attributes.candidateStrategy == CandidateStrategy.DEPT_MEMBER ||
currentNode.attributes.candidateStrategy == CandidateStrategy.DEPT_LEADER
"
label=
"指定部门"
prop=
"candidateParam"
span=
"24"
>
<el-tree-select
ref=
"treeRef"
v-model=
"candidateParamArray"
:data=
"deptTreeOptions"
:props=
"defaultProps"
empty-text=
"加载中,请稍后"
multiple
node-key=
"id"
style=
"width: 100%"
show-checkbox
/>
</el-form-item>
<el-form-item
v-if=
"currentNode.attributes.candidateStrategy == CandidateStrategy.POST"
label=
"指定岗位"
prop=
"candidateParam"
span=
"24"
>
<el-select
v-model=
"candidateParamArray"
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=
"currentNode.attributes.candidateStrategy == CandidateStrategy.USER"
label=
"指定用户"
prop=
"candidateParam"
span=
"24"
>
<el-select
v-model=
"candidateParamArray"
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=
"currentNode.attributes.candidateStrategy === CandidateStrategy.USER_GROUP"
label=
"指定用户组"
prop=
"candidateParam"
>
<el-select
v-model=
"candidateParamArray"
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=
"currentNode.attributes.candidateStrategy === CandidateStrategy.EXPRESSION"
label=
"流程表达式"
prop=
"candidateParam"
>
<el-input
type=
"textarea"
v-model=
"candidateParamArray[0]"
clearable
style=
"width: 100%"
/>
</el-form-item>
</el-form>
</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
setup
lang=
'ts'
>
import
{
SimpleFlowNode
,
CandidateStrategy
}
from
'../consts'
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
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'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
defineOptions
({
name
:
'CopyTaskNodeConfig'
})
const
props
=
defineProps
({
flowNode
:
{
type
:
Object
as
()
=>
SimpleFlowNode
,
required
:
true
}
})
// 定义事件,更新父组件
const
emits
=
defineEmits
<
{
'update:modelValue'
:
[
node
:
SimpleFlowNode
]
}
>
()
// 是否可见
const
settingVisible
=
ref
(
false
)
// 当前节点信息,保存后,需要更新父组件
const
currentNode
=
ref
<
SimpleFlowNode
>
(
props
.
flowNode
)
const
roleOptions
=
inject
<
Ref
<
RoleApi
.
RoleVO
[]
>>
(
'roleList'
)
// 角色列表
const
postOptions
=
inject
<
Ref
<
PostApi
.
PostVO
[]
>>
(
'postList'
)
// 岗位列表
const
userOptions
=
inject
<
Ref
<
UserApi
.
UserVO
[]
>>
(
'userList'
)
// 用户列表
const
deptOptions
=
inject
<
Ref
<
DeptApi
.
DeptVO
[]
>>
(
'deptList'
)
// 部门列表
const
userGroupOptions
=
inject
<
Ref
<
UserGroupApi
.
UserGroupVO
[]
>>
(
'userGroupList'
)
// 用户组列表
const
deptTreeOptions
=
ref
()
// 部门树
deptTreeOptions
.
value
=
handleTree
(
deptOptions
?.
value
as
DeptApi
.
DeptVO
[],
'id'
)
// 抄送人策略, 去掉发起人自选
const
copyUserStrategies
=
computed
(
()
=>
{
return
getIntDictOptions
(
DICT_TYPE
.
BPM_TASK_CANDIDATE_STRATEGY
)
.
filter
(
item
=>
item
.
value
!==
CandidateStrategy
.
START_USER_SELECT
);
})
// 选中的参数
const
candidateParamArray
=
ref
<
any
[]
>
([])
// 关闭
const
closeDrawer
=
()
=>
{
settingVisible
.
value
=
false
}
// 保存配置
const
saveConfig
=
()
=>
{
currentNode
.
value
.
attributes
.
candidateParam
=
candidateParamArray
.
value
?.
join
(
','
)
currentNode
.
value
.
showText
=
getShowText
()
emits
(
'update:modelValue'
,
currentNode
.
value
)
settingVisible
.
value
=
false
}
const
open
=
()
=>
{
settingVisible
.
value
=
true
}
defineExpose
({
open
})
// 提供 open 方法,用于打开抄送人配置抽屉
const
changeCandidateStrategy
=
()
=>
{
candidateParamArray
.
value
=
[]
}
// TODO 貌似可以和 UserTaskNodeConfig 重复了, 如何共用??
const
getShowText
=
()
:
string
=>
{
let
showText
=
''
// 指定成员
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
USER
)
{
if
(
candidateParamArray
.
value
?.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
userOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
candidateParamArray
.
value
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
nickname
)
}
})
console
.
log
(
"candidateNames is "
,
candidateNames
)
showText
=
`指定成员:
${
candidateNames
.
join
(
','
)}
`
}
}
// 指定角色
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
ROLE
)
{
if
(
candidateParamArray
.
value
?.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
roleOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
candidateParamArray
.
value
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
name
)
}
})
showText
=
`指定角色:
${
candidateNames
.
join
(
','
)}
`
}
}
// 指定部门
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
DEPT_MEMBER
||
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
DEPT_LEADER
)
{
if
(
candidateParamArray
.
value
?.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
deptOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
candidateParamArray
.
value
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
name
)
}
})
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
DEPT_MEMBER
){
showText
=
`部门成员:
${
candidateNames
.
join
(
','
)}
`
}
else
{
showText
=
`部门的负责人:
${
candidateNames
.
join
(
','
)}
`
}
}
}
// 指定岗位
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
POST
)
{
if
(
candidateParamArray
.
value
?.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
postOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
candidateParamArray
.
value
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
name
)
}
})
showText
=
`指定岗位:
${
candidateNames
.
join
(
','
)}
`
}
}
// 指定用户组
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
USER_GROUP
)
{
if
(
candidateParamArray
.
value
?.
length
>
0
)
{
const
candidateNames
:
string
[]
=
[]
userGroupOptions
?.
value
.
forEach
((
item
)
=>
{
if
(
candidateParamArray
.
value
.
includes
(
item
.
id
))
{
candidateNames
.
push
(
item
.
name
)
}
})
showText
=
`指定用户组:
${
candidateNames
.
join
(
','
)}
`
}
}
// 流程表达式
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
EXPRESSION
)
{
if
(
candidateParamArray
.
value
?.
length
>
0
)
{
showText
=
`流程表达式:
${
candidateParamArray
.
value
[
0
]}
`
}
}
return
showText
}
onMounted
(
async
()
=>
{
console
.
log
(
'candidateParam'
,
currentNode
.
value
.
attributes
?.
candidateParam
)
candidateParamArray
.
value
=
currentNode
.
value
.
attributes
?.
candidateParam
?.
split
(
','
).
map
(
item
=>
+
item
)
console
.
log
(
'candidateParamArray.value'
,
candidateParamArray
.
value
)
})
</
script
>
<
style
lang=
"scss"
scoped
>
::v-deep
(
.el-divider--horizontal
)
{
display
:
block
;
height
:
1px
;
margin
:
0
;
border-top
:
1px
var
(
--el-border-color
)
var
(
--el-border-style
);
}
</
style
>
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
View file @
ee895d07
...
...
@@ -204,7 +204,7 @@ const saveConfig = () => {
emits
(
'update:modelValue'
,
currentNode
.
value
)
settingVisible
.
value
=
false
}
const
getShowText
=
():
string
=>
{
const
getShowText
=
()
:
string
=>
{
let
showText
=
''
// 指定成员
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
USER
)
{
...
...
@@ -290,11 +290,11 @@ const getShowText = (): string => {
const
open
=
()
=>
{
settingVisible
.
value
=
true
}
defineExpose
({
open
})
// 提供 open 方法,用于打开
弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开
抽屉
const
changeCandidateStrategy
=
()
=>
{
candidateParamArray
.
value
=
[]
currentNode
.
value
.
attributes
.
approveMethod
=
1
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
30
)
{
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
USER
)
{
notAllowedMultiApprovers
.
value
=
true
}
else
{
notAllowedMultiApprovers
.
value
=
false
...
...
@@ -302,7 +302,7 @@ const changeCandidateStrategy = () => {
}
const
changedCandidateUsers
=
()
=>
{
if
(
candidateParamArray
.
value
?.
length
<=
1
&&
currentNode
.
value
.
attributes
?.
candidateStrategy
===
30
)
{
if
(
candidateParamArray
.
value
?.
length
<=
1
&&
currentNode
.
value
.
attributes
?.
candidateStrategy
===
CandidateStrategy
.
USER
)
{
currentNode
.
value
.
attributes
.
approveMethod
=
1
;
notAllowedMultiApprovers
.
value
=
true
}
else
{
...
...
@@ -323,7 +323,7 @@ onMounted(async () => {
console
.
log
(
'candidateParam'
,
currentNode
.
value
.
attributes
?.
candidateParam
)
candidateParamArray
.
value
=
currentNode
.
value
.
attributes
?.
candidateParam
?.
split
(
','
).
map
(
item
=>
+
item
)
console
.
log
(
'candidateParamArray.value'
,
candidateParamArray
.
value
)
if
(
currentNode
.
value
.
attributes
?.
candidateStrategy
===
30
&&
candidateParamArray
.
value
?.
length
<=
1
)
{
if
(
currentNode
.
value
.
attributes
?.
candidateStrategy
===
CandidateStrategy
.
USER
&&
candidateParamArray
.
value
?.
length
<=
1
)
{
notAllowedMultiApprovers
.
value
=
true
}
else
{
notAllowedMultiApprovers
.
value
=
false
...
...
src/components/SimpleProcessDesignerV2/src/nodes/CopyTaskNode.vue
0 → 100644
View file @
ee895d07
<
template
>
<div
class=
"node-wrapper"
>
<div
class=
"node-container"
>
<div
class=
"node-box"
:class=
"
{'node-config-error': !currentNode.showText}">
<div
class=
"node-title-container"
>
<div
class=
"node-title-icon copy-task"
><span
class=
"iconfont icon-copy"
></span></div>
<input
v-if=
"showInput"
type=
"text"
class=
"editable-title-input"
@
blur=
"blurEvent($event)"
v-mountedFocus
v-model=
"currentNode.name"
:placeholder=
"currentNode.name"
/>
<div
v-else
class=
"node-title"
@
click=
"clickEvent"
>
{{
currentNode
.
name
}}
</div>
</div>
<div
class=
"node-content"
@
click=
"openNodeConfig"
>
<div
class=
"node-text"
:title=
"currentNode.showText"
v-if=
"currentNode.showText"
>
{{
currentNode
.
showText
}}
</div>
<div
class=
"node-text"
v-else
>
{{
NODE_DEFAULT_TEXT
.
get
(
NodeType
.
COPY_TASK_NODE
)
}}
</div>
<Icon
icon=
"ep:arrow-right-bold"
/>
</div>
<div
class=
"node-toolbar"
>
<!--
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:document-copy"
@
click=
"copyNode"
/></div>
-->
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:delete"
@
click=
"deleteNode"
/></div>
</div>
</div>
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
<NodeHandler
v-if=
"currentNode"
v-model:child-node=
"currentNode.childNode"
/>
</div>
<CopyTaskNodeConfig
v-if=
"currentNode"
ref=
"nodeSetting"
:flow-node=
"currentNode"
@
update:model-value=
"handleModelValueUpdate"
/>
</div>
</
template
>
<
script
setup
lang=
'ts'
>
import
{
SimpleFlowNode
,
NodeType
,
NODE_DEFAULT_TEXT
,
NODE_DEFAULT_NAME
}
from
'../consts'
import
NodeHandler
from
'../NodeHandler.vue'
import
CopyTaskNodeConfig
from
'../nodes-config/CopyTaskNodeConfig.vue'
;
defineOptions
({
name
:
'CopyTaskNode'
})
const
props
=
defineProps
({
flowNode
:
{
type
:
Object
as
()
=>
SimpleFlowNode
,
required
:
true
}
})
// 定义事件,更新父组件。
const
emits
=
defineEmits
<
{
'update:modelValue'
:
[
node
:
SimpleFlowNode
|
undefined
]
}
>
()
const
currentNode
=
ref
<
SimpleFlowNode
>
(
props
.
flowNode
)
// 监控当前节点的变化
watch
(
()
=>
props
.
flowNode
,
(
newValue
)
=>
{
currentNode
.
value
=
newValue
}
)
// 显示节点名称输入框
const
showInput
=
ref
(
false
)
// 节点名称输入框失去焦点
const
blurEvent
=
(
event
)
=>
{
showInput
.
value
=
false
currentNode
.
value
.
name
=
currentNode
.
value
.
name
||
NODE_DEFAULT_NAME
.
get
(
NodeType
.
USER_TASK_NODE
)
as
string
}
// 点击节点标题进行输入
const
clickEvent
=
()
=>
{
showInput
.
value
=
true
}
const
nodeSetting
=
ref
()
// 打开节点配置
const
openNodeConfig
=
()
=>
{
nodeSetting
.
value
.
open
()
}
// 删除节点。更新当前节点为孩子节点
const
deleteNode
=
()
=>
{
console
.
log
(
'the child node is '
,
currentNode
.
value
.
childNode
)
emits
(
'update:modelValue'
,
currentNode
.
value
.
childNode
)
}
// 接收抄送人配置组件传过来的事件,并且更新节点 信息
const
handleModelValueUpdate
=
(
updateValue
)
=>
{
emits
(
'update:modelValue'
,
updateValue
)
}
</
script
>
<
style
lang=
'scss'
scoped
>
</
style
>
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
View file @
ee895d07
...
...
@@ -3,13 +3,12 @@
<div
class=
"node-container"
>
<div
class=
"node-box"
:class=
"
{'node-config-error': !flowNode.showText}">
<div
class=
"node-title-container"
>
<div
class=
"node-title-icon
"
><Icon
icon=
"ep:avatar"
/
></div>
<div
class=
"node-title-icon
user-task"
><span
class=
"iconfont icon-approve"
></span
></div>
<input
v-if=
"showInput"
type=
"text"
class=
"editable-title-input"
@
blur=
"blurEvent($event)"
@
focus=
"focusEvent($event)"
v-mountedFocus
v-model=
"currentNode.name"
:placeholder=
"currentNode.name"
...
...
@@ -18,7 +17,7 @@
{{
currentNode
.
name
}}
</div>
</div>
<div
class=
"node-content"
@
click=
"
commo
nNodeConfig"
>
<div
class=
"node-content"
@
click=
"
ope
nNodeConfig"
>
<div
class=
"node-text"
:title=
"flowNode.showText"
v-if=
"flowNode.showText"
>
{{
flowNode
.
showText
}}
</div>
...
...
@@ -32,8 +31,6 @@
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:delete"
@
click=
"deleteNode"
/></div>
</div>
</div>
<!-- title="朱文宣妈妈, 许颖嘉, 王禹昊妈妈, 王亦心爸爸, 朱彧兮妈妈, 陈语馨爸爸, 蔡知妤爸爸/蔡知妍爸爸, 蒋昂倬妈妈, 胡恒智爸爸, 杨晞宇妈妈, 赵嘉依妈妈, 罗嘉懿爸爸, 郑辰希妈妈, 周慕然爸爸, 方张霖妈妈, 张若轩妈妈, 王亦心妈妈, 董子夏妈妈, 刘昱君妈妈/刘畅妈妈, 李子琦妈妈, 解宛芙妈妈, 洪栎妈妈, 陈涂晟爸爸, 张泽锴妈妈, 杨晞宇爸爸, 高鸿轩妈妈, 张然妈妈, 景晗亿妈妈, 郑炜彤妈妈, 祝安屹妈妈, 王萧婉妈妈, 朱彧兮爸爸, 李沐辰妈妈, 王元昊爸爸, 罗嘉懿妈妈, 陈语馨妈妈" -->
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
<NodeHandler
v-if=
"currentNode"
v-model:child-node=
"currentNode.childNode"
/>
</div>
...
...
@@ -51,7 +48,7 @@ import NodeHandler from '../NodeHandler.vue'
import
UserTaskNodeConfig
from
'../nodes-config/UserTaskNodeConfig.vue'
;
import
{
generateUUID
}
from
'@/utils'
defineOptions
({
name
:
'
Common
Node'
name
:
'
UserTask
Node'
})
const
props
=
defineProps
({
flowNode
:
{
...
...
@@ -62,32 +59,27 @@ const props = defineProps({
const
emits
=
defineEmits
<
{
'update:modelValue'
:
[
node
:
SimpleFlowNode
|
undefined
]
}
>
()
const
currentNode
=
ref
<
SimpleFlowNode
>
(
props
.
flowNode
)
const
nodeSetting
=
ref
()
const
commonNodeConfig
=
()
=>
{
console
.
log
(
'nodeSetting'
,
nodeSetting
)
// 打开节点配置
const
openNodeConfig
=
()
=>
{
nodeSetting
.
value
.
open
()
}
const
currentNode
=
ref
<
SimpleFlowNode
>
(
props
.
flowNode
)
console
.
log
(
'current common node is '
,
currentNode
)
// 不加这个 COPY 会有问题
watch
(
()
=>
props
.
flowNode
,
(
newValue
)
=>
{
console
.
log
(
'new value is '
,
newValue
)
currentNode
.
value
=
newValue
}
)
// 显示节点名称输入框
const
showInput
=
ref
(
false
)
// 节点名称输入框失去焦点
const
blurEvent
=
(
event
)
=>
{
console
.
log
(
'blurEvent'
,
event
)
showInput
.
value
=
false
currentNode
.
value
.
name
=
currentNode
.
value
.
name
||
NODE_DEFAULT_NAME
.
get
(
NodeType
.
USER_TASK_NODE
)
as
string
}
const
focusEvent
=
(
event
:
FocusEvent
)
=>
{
console
.
log
(
'focusEvent'
,
event
)
}
// 点击节点标题进行输入
const
clickEvent
=
()
=>
{
showInput
.
value
=
true
}
...
...
@@ -115,7 +107,6 @@ const copyNode = () => {
childNode
:
currentNode
.
value
}
currentNode
.
value
=
newCopyNode
console
.
log
(
'current node value'
,
currentNode
.
value
)
emits
(
'update:modelValue'
,
currentNode
.
value
)
}
</
script
>
...
...
src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss
View file @
ee895d07
...
...
@@ -108,6 +108,13 @@
.node-title-icon
{
display
:
flex
;
align-items
:
center
;
&
.user-task
{
color
:
#ff943e
;
}
&
.copy-task
{
color
:
#3296fa
;
}
}
.node-title
{
...
...
@@ -118,7 +125,7 @@
overflow
:
hidden
;
text-overflow
:
ellipsis
;
color
:
#1f1f1f
;
// vertical-align: middle
;
line-height
:
18px
;
}
}
...
...
@@ -458,7 +465,7 @@
text-align
:
center
;
&
:hover
{
background
:
#
3296fa
;
background
:
#
e2e2e2
;
box-shadow
:
0
2px
4px
0
rgba
(
0
,
0
,
0
,
0
.1
);
}
...
...
@@ -466,11 +473,14 @@
font-size
:
35px
;
line-height
:
80px
;
}
}
}
.approve
{
color
:
#ff943e
;
}
}
.copy
{
color
:
#3296fa
;
}
.handler-item-text
{
margin-top
:
4px
;
...
...
src/views/bpm/simpleWorkflow/index.vue
View file @
ee895d07
...
...
@@ -5,6 +5,11 @@
import
{
SimpleProcessDesigner
}
from
'@/components/SimpleProcessDesignerV2/src/'
;
import
{
getModel
}
from
'@/api/bpm/model'
import
{
getForm
,
FormVO
}
from
'@/api/bpm/form'
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'
defineOptions
({
name
:
'SimpleWorkflowDesignEditor'
})
...
...
@@ -12,8 +17,18 @@ const { query } = useRoute() // 路由的查询
const
modelId
:
string
|
undefined
=
query
.
modelId
as
string
;
const
formFields
=
ref
<
string
[]
>
([])
const
formType
=
ref
(
20
);
const
roleOptions
=
ref
<
RoleApi
.
RoleVO
[]
>
([])
// 角色列表
const
postOptions
=
ref
<
PostApi
.
PostVO
[]
>
([])
// 岗位列表
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
const
deptOptions
=
ref
<
DeptApi
.
DeptVO
[]
>
([])
// 部门列表
const
userGroupOptions
=
ref
<
UserGroupApi
.
UserGroupVO
[]
>
([])
// 用户组列表
provide
(
'formFields'
,
formFields
)
provide
(
'formType'
,
formType
)
provide
(
'roleList'
,
roleOptions
)
provide
(
'postList'
,
postOptions
)
provide
(
'userList'
,
userOptions
)
provide
(
'deptList'
,
deptOptions
)
provide
(
'userGroupList'
,
userGroupOptions
)
onMounted
(
async
()
=>
{
const
bpmnModel
=
await
getModel
(
modelId
);
if
(
bpmnModel
)
{
...
...
@@ -23,6 +38,16 @@ onMounted( async () => {
formFields
.
value
=
bpmnForm
?.
fields
}
}
// 获得角色列表
roleOptions
.
value
=
await
RoleApi
.
getSimpleRoleList
()
postOptions
.
value
=
await
PostApi
.
getSimplePostList
()
// 获得用户列表
userOptions
.
value
=
await
UserApi
.
getSimpleUserList
()
// 获得部门列表
deptOptions
.
value
=
await
DeptApi
.
getSimpleDeptList
()
console
.
log
(
'index deptOptions value is'
,
deptOptions
.
value
)
// 用户组列表
userGroupOptions
.
value
=
await
UserGroupApi
.
getUserGroupSimpleList
()
})
</
script
>
<
style
lang=
'scss'
scoped
>
...
...
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