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
676ed6bd
authored
Apr 27, 2024
by
jason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
仿钉钉流程设计器-前端审批人节点改造.
parent
93141792
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
540 additions
and
27 deletions
+540
-27
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
+2
-2
src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue
+10
-6
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
+28
-19
src/components/SimpleProcessDesignerV2/src/consts.ts
+37
-0
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
+341
-0
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
+122
-0
No files found.
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
View file @
676ed6bd
...
...
@@ -25,7 +25,7 @@
</template>
<
script
setup
lang=
"ts"
>
import
{
SimpleFlowNode
,
NodeType
,
NODE_DEFAULT_NAME
}
from
'./consts'
import
{
SimpleFlowNode
,
NodeType
,
NODE_DEFAULT_NAME
,
CandidateStrategy
,
APPROVE_METHODS
}
from
'./consts'
import
{
generateUUID
}
from
'@/utils'
defineOptions
({
name
:
'NodeHandler'
...
...
@@ -57,7 +57,7 @@ const addNode = (type: number) => {
// 审批节点配置
attributes
:
{
approveMethod
:
1
,
candidateStrategy
:
30
,
candidateStrategy
:
CandidateStrategy
.
USER
,
candidateParam
:
undefined
},
childNode
:
props
.
childNode
...
...
src/components/SimpleProcessDesignerV2/src/ProcessNodeTree.vue
View file @
676ed6bd
<
template
>
<!-- 开始节点 -->
<StartEventNode
v-if=
"currentNode && currentNode.type === NodeType.START_EVENT_NODE"
:flow-node =
"currentNode"
/>
<!-- 审批节点 -->
<UserTaskNode
v-if=
"currentNode && currentNode.type === NodeType.USER_TASK_NODE"
:flow-node =
"currentNode"
@
update:model-value=
"handleModelValueUpdate"
/>
<!-- 递归显示子节点 -->
<!-- 递归显示
孩
子节点 -->
<ProcessNodeTree
v-if=
"currentNode && currentNode.childNode"
v-model:flow-node=
"currentNode.childNode"
/>
<!-- 结束节点 -->
...
...
@@ -11,7 +15,7 @@
<
script
setup
lang=
'ts'
>
import
StartEventNode
from
'./nodes/StartEventNode.vue'
;
import
EndEventNode
from
'./nodes/EndEventNode.vue'
;
import
UserTaskNode
from
'./nodes/UserTaskNode.vue'
;
import
{
SimpleFlowNode
,
NodeType
}
from
'./consts'
;
defineOptions
({
name
:
'ProcessNodeTree'
...
...
@@ -32,10 +36,10 @@ watch(() => props.flowNode, (newValue) => {
currentNode
.
value
=
newValue
;
});
//
const handleModelValueUpdate = (updateValue) => {
// console.log('
handleModelValueUpdate', updateValue)
//
emits('update:flowNode', updateValue);
//
}
const
handleModelValueUpdate
=
(
updateValue
)
=>
{
console
.
log
(
'Process Node Tree
handleModelValueUpdate'
,
updateValue
)
emits
(
'update:flowNode'
,
updateValue
);
}
</
script
>
<
style
lang=
'scss'
scoped
>
...
...
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
View file @
676ed6bd
...
...
@@ -19,8 +19,9 @@
</div>
</div>
<Dialog
v-model=
"errorDialogVisible"
title=
"保存失败"
width=
"400"
:fullscreen=
"false"
>
<div
v-for=
"(item, index) in errorNodes"
:key=
"index"
>
{{
item
.
name
}}
<div
class=
"mb-2"
>
以下节点内容不完善,请修改后保存
</div>
<div
class=
"mb-3 b-rounded-1 bg-gray-100 p-2 line-height-normal"
v-for=
"(item, index) in errorNodes"
:key=
"index"
>
{{
item
.
name
}}
:
{{
NODE_DEFAULT_TEXT
.
get
(
item
.
type
)
}}
</div>
<template
#
footer
>
<el-button
type=
"primary"
@
click=
"errorDialogVisible = false"
>
知道了
</el-button>
...
...
@@ -32,7 +33,7 @@
<
script
setup
lang=
"ts"
>
import
ProcessNodeTree
from
'./ProcessNodeTree.vue'
;
import
{
saveBpmSimpleModel
,
getBpmSimpleModel
}
from
'@/api/bpm/simple'
import
{
SimpleFlowNode
,
NodeType
}
from
'./consts'
import
{
SimpleFlowNode
,
NodeType
,
NODE_DEFAULT_TEXT
}
from
'./consts'
defineOptions
({
name
:
'SimpleProcessDesigner'
...
...
@@ -67,21 +68,24 @@ const saveSimpleFlowModel = async () => {
console
.
log
(
'errorNodes is '
,
errorNodes
)
if
(
errorNodes
.
length
>
0
)
{
errorDialogVisible
.
value
=
true
return
;
}
// const data = {
// modelId: props.modelId,
// simpleModelBody: simpleWorkFlowNodes.value
// }
// console.log('request json data1 is ', data)
// const result = await saveBpmSimpleModel(data)
// console.log('save the result is ', result)
// if (result) {
// message.success('修改成功')
// close()
// } else {
// message.alert('修改失败')
// }
const
data
=
{
modelId
:
props
.
modelId
,
simpleModelBody
:
processNodeTree
.
value
}
const
result
=
await
saveBpmSimpleModel
(
data
)
console
.
log
(
'save the result is '
,
result
)
if
(
result
)
{
message
.
success
(
'修改成功'
)
close
()
}
else
{
message
.
alert
(
'修改失败'
)
}
}
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
const
validateNode
=
(
node
:
SimpleFlowNode
|
undefined
,
errorNodes
:
SimpleFlowNode
[])
=>
{
if
(
node
)
{
const
{
type
,
showText
,
conditionNodes
}
=
node
...
...
@@ -113,23 +117,28 @@ const validateNode = (node: SimpleFlowNode | undefined, errorNodes: SimpleFlowNo
}
}
}
const
close
=
()
=>
{
router
.
push
({
path
:
'/bpm/manager/model'
})
}
let
scaleValue
=
ref
(
100
)
const
MAX_SCALE_VALUE
=
200
const
MIN_SCALE_VALUE
=
50
// 放大
const
zoomOut
=
()
=>
{
if
(
scaleValue
.
value
==
300
)
{
if
(
scaleValue
.
value
==
MAX_SCALE_VALUE
)
{
return
}
scaleValue
.
value
+=
10
}
// 缩小
const
zoomIn
=
()
=>
{
if
(
scaleValue
.
value
==
50
)
{
if
(
scaleValue
.
value
==
MIN_SCALE_VALUE
)
{
return
}
scaleValue
.
value
-=
10
}
onMounted
(
async
()
=>
{
const
result
=
await
getBpmSimpleModel
(
props
.
modelId
)
if
(
result
)
{
...
...
src/components/SimpleProcessDesignerV2/src/consts.ts
View file @
676ed6bd
...
...
@@ -42,6 +42,43 @@ export enum NodeType {
INCLUSIVE_NODE_JOIN
=
8
}
// 候选人策略 (用于审批节点。抄送节点
export
enum
CandidateStrategy
{
/**
* 指定角色
*/
ROLE
=
10
,
/**
* 指定部门成员
*/
DEPT_MEMBER
=
20
,
/**
* 部门的负责人
*/
DEPT_LEADER
=
21
,
/**
* 指定岗位
*/
POST
=
22
,
/**
* 指定用户
*/
USER
=
30
,
/**
* 发起人自选
*/
START_USER_SELECT
=
35
,
/**
* 指定用户组
*/
USER_GROUP
=
40
,
/**
* 流程表达式
*/
EXPRESSION
=
60
}
export
type
SimpleFlowNode
=
{
id
:
string
,
type
:
NodeType
,
...
...
src/components/SimpleProcessDesignerV2/src/nodes-config/UserTaskNodeConfig.vue
0 → 100644
View file @
676ed6bd
<
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 getIntDictOptions(DICT_TYPE.BPM_TASK_CANDIDATE_STRATEGY)"
: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%"
@
change=
"changedCandidateUsers"
>
<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-item
label=
"审批方式"
prop=
"approveMethod"
>
<el-radio-group
v-model=
"currentNode.attributes.approveMethod"
>
<div
class=
"flex-col"
>
<div
v-for=
"(item, index) in APPROVE_METHODS"
:key=
"index"
>
<el-radio
:value=
"item.value"
:label=
"item.value"
:disabled=
"item.value !== 1 && notAllowedMultiApprovers"
>
{{ item.label }}
</el-radio>
</div>
</div>
</el-radio-group>
</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
,
APPROVE_METHODS
,
CandidateStrategy
}
from
'../consts'
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'
defineOptions
({
name
:
'UserTaskNodeConfig'
})
const
props
=
defineProps
({
flowNode
:
{
type
:
Object
as
()
=>
SimpleFlowNode
,
required
:
true
}
})
const
emits
=
defineEmits
<
{
'update:modelValue'
:
[
node
:
SimpleFlowNode
]
}
>
()
const
notAllowedMultiApprovers
=
ref
(
false
)
const
currentNode
=
ref
<
SimpleFlowNode
>
(
props
.
flowNode
)
const
settingVisible
=
ref
(
false
)
const
roleOptions
=
ref
<
RoleApi
.
RoleVO
[]
>
([])
// 角色列表
const
postOptions
=
ref
<
PostApi
.
PostVO
[]
>
([])
// 岗位列表
const
userOptions
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 用户列表
let
deptOptions
:
DeptApi
.
DeptVO
[]
=
[]
// 部门列表
const
deptTreeOptions
=
ref
()
// 部门树
const
userGroupOptions
=
ref
<
UserGroupApi
.
UserGroupVO
[]
>
([])
// 用户组列表
const
candidateParamArray
=
ref
<
any
[]
>
([])
const
closeDrawer
=
()
=>
{
settingVisible
.
value
=
false
}
const
saveConfig
=
()
=>
{
currentNode
.
value
.
attributes
.
candidateParam
=
candidateParamArray
.
value
?.
join
(
','
)
currentNode
.
value
.
showText
=
getShowText
()
console
.
log
(
'currentNode value is '
,
currentNode
.
value
)
emits
(
'update:modelValue'
,
currentNode
.
value
)
settingVisible
.
value
=
false
}
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
===
10
)
{
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
.
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
.
START_USER_SELECT
)
{
showText
=
`发起人自选`
}
// 流程表达式
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
CandidateStrategy
.
EXPRESSION
)
{
if
(
candidateParamArray
.
value
?.
length
>
0
)
{
showText
=
`流程表达式:
${
candidateParamArray
.
value
[
0
]}
`
}
}
return
showText
}
const
open
=
()
=>
{
settingVisible
.
value
=
true
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
const
changeCandidateStrategy
=
()
=>
{
candidateParamArray
.
value
=
[]
currentNode
.
value
.
attributes
.
approveMethod
=
1
if
(
currentNode
.
value
.
attributes
.
candidateStrategy
===
30
)
{
notAllowedMultiApprovers
.
value
=
true
}
else
{
notAllowedMultiApprovers
.
value
=
false
}
}
const
changedCandidateUsers
=
()
=>
{
if
(
candidateParamArray
.
value
?.
length
<=
1
&&
currentNode
.
value
.
attributes
?.
candidateStrategy
===
30
)
{
currentNode
.
value
.
attributes
.
approveMethod
=
1
;
notAllowedMultiApprovers
.
value
=
true
}
else
{
notAllowedMultiApprovers
.
value
=
false
}
}
onMounted
(
async
()
=>
{
// 获得角色列表
roleOptions
.
value
=
await
RoleApi
.
getSimpleRoleList
()
postOptions
.
value
=
await
PostApi
.
getSimplePostList
()
// 获得用户列表
userOptions
.
value
=
await
UserApi
.
getSimpleUserList
()
// 获得部门列表
deptOptions
=
await
DeptApi
.
getSimpleDeptList
()
deptTreeOptions
.
value
=
handleTree
(
deptOptions
,
'id'
)
// 获得用户组列表
userGroupOptions
.
value
=
await
UserGroupApi
.
getUserGroupSimpleList
()
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
)
{
notAllowedMultiApprovers
.
value
=
true
}
else
{
notAllowedMultiApprovers
.
value
=
false
}
})
</
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/UserTaskNode.vue
0 → 100644
View file @
676ed6bd
<
template
>
<div
class=
"node-wrapper"
>
<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>
<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"
/>
<div
v-else
class=
"node-title"
@
click=
"clickEvent"
>
{{
currentNode
.
name
}}
</div>
</div>
<div
class=
"node-content"
@
click=
"commonNodeConfig"
>
<div
class=
"node-text"
:title=
"flowNode.showText"
v-if=
"flowNode.showText"
>
{{
flowNode
.
showText
}}
</div>
<div
class=
"node-text"
v-else
>
{{
NODE_DEFAULT_TEXT
.
get
(
NodeType
.
USER_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>
<!-- title="朱文宣妈妈, 许颖嘉, 王禹昊妈妈, 王亦心爸爸, 朱彧兮妈妈, 陈语馨爸爸, 蔡知妤爸爸/蔡知妍爸爸, 蒋昂倬妈妈, 胡恒智爸爸, 杨晞宇妈妈, 赵嘉依妈妈, 罗嘉懿爸爸, 郑辰希妈妈, 周慕然爸爸, 方张霖妈妈, 张若轩妈妈, 王亦心妈妈, 董子夏妈妈, 刘昱君妈妈/刘畅妈妈, 李子琦妈妈, 解宛芙妈妈, 洪栎妈妈, 陈涂晟爸爸, 张泽锴妈妈, 杨晞宇爸爸, 高鸿轩妈妈, 张然妈妈, 景晗亿妈妈, 郑炜彤妈妈, 祝安屹妈妈, 王萧婉妈妈, 朱彧兮爸爸, 李沐辰妈妈, 王元昊爸爸, 罗嘉懿妈妈, 陈语馨妈妈" -->
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
<NodeHandler
v-if=
"currentNode"
v-model:child-node=
"currentNode.childNode"
/>
</div>
</div>
<UserTaskNodeConfig
v-if=
"currentNode"
ref=
"nodeSetting"
:flow-node=
"currentNode"
@
update:model-value=
"handleModelValueUpdate"
/>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
SimpleFlowNode
,
NodeType
,
NODE_DEFAULT_TEXT
,
NODE_DEFAULT_NAME
}
from
'../consts'
import
NodeHandler
from
'../NodeHandler.vue'
import
UserTaskNodeConfig
from
'../nodes-config/UserTaskNodeConfig.vue'
;
import
{
generateUUID
}
from
'@/utils'
defineOptions
({
name
:
'CommonNode'
})
const
props
=
defineProps
({
flowNode
:
{
type
:
Object
as
()
=>
SimpleFlowNode
,
required
:
true
}
})
const
emits
=
defineEmits
<
{
'update:modelValue'
:
[
node
:
SimpleFlowNode
|
undefined
]
}
>
()
const
nodeSetting
=
ref
()
const
commonNodeConfig
=
()
=>
{
console
.
log
(
'nodeSetting'
,
nodeSetting
)
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
}
const
handleModelValueUpdate
=
(
updateValue
)
=>
{
emits
(
'update:modelValue'
,
updateValue
)
console
.
log
(
'user task node handleModelValueUpdate'
,
updateValue
)
}
const
deleteNode
=
()
=>
{
console
.
log
(
'the child node is '
,
currentNode
.
value
.
childNode
)
emits
(
'update:modelValue'
,
currentNode
.
value
.
childNode
)
}
const
copyNode
=
()
=>
{
// const oldChildNode = currentNode.value.childNode
const
newCopyNode
:
SimpleFlowNode
=
{
id
:
generateUUID
(),
name
:
currentNode
.
value
.
name
,
showText
:
currentNode
.
value
.
showText
,
type
:
currentNode
.
value
.
type
,
// 审批节点配置
attributes
:
{
approveMethod
:
currentNode
.
value
.
attributes
?.
approveMethod
,
candidateStrategy
:
currentNode
.
value
.
attributes
?.
candidateStrategy
,
candidateParam
:
currentNode
.
value
.
attributes
?.
candidateParam
},
childNode
:
currentNode
.
value
}
currentNode
.
value
=
newCopyNode
console
.
log
(
'current node value'
,
currentNode
.
value
)
emits
(
'update:modelValue'
,
currentNode
.
value
)
}
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
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