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
e8193a0a
authored
Apr 30, 2024
by
jason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
仿钉钉流程设计器- 完善条件分支节点
parent
9a2dcf20
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
123 additions
and
52 deletions
+123
-52
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
+2
-2
src/components/SimpleProcessDesignerV2/src/consts.ts
+1
-2
src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue
+9
-9
src/components/SimpleProcessDesignerV2/src/nodes/CopyTaskNode.vue
+1
-1
src/components/SimpleProcessDesignerV2/src/nodes/ExclusiveNode.vue
+51
-33
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
+1
-1
src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss
+58
-4
No files found.
src/components/SimpleProcessDesignerV2/src/NodeHandler.vue
View file @
e8193a0a
...
...
@@ -100,7 +100,7 @@ const addNode = (type: number) => {
childNode
:
undefined
,
attributes
:
{
conditionType
:
1
,
default
Condition
:
false
default
Flow
:
false
}
},
{
...
...
@@ -111,7 +111,7 @@ const addNode = (type: number) => {
childNode
:
undefined
,
attributes
:
{
conditionType
:
undefined
,
default
Condition
:
true
default
Flow
:
true
}
}
]
...
...
src/components/SimpleProcessDesignerV2/src/consts.ts
View file @
e8193a0a
...
...
@@ -115,6 +115,5 @@ export const APPROVE_METHODS: DictDataVO [] = [
]
export
const
CONDITION_CONFIG_TYPES
:
DictDataVO
[]
=
[
{
label
:
'条件规则'
,
value
:
1
},
{
label
:
'条件表达式'
,
value
:
2
}
{
label
:
'自定义条件表达式'
,
value
:
1
}
]
src/components/SimpleProcessDesignerV2/src/nodes-config/ConditionNodeConfig.vue
View file @
e8193a0a
...
...
@@ -13,10 +13,10 @@
</div>
</
template
>
<div>
<div
class=
"mb-3 text-size-sm"
v-if=
"currentNode.attributes.default
Condition
"
>
其它条件不满足进入此分支(该分支不可编辑和删除)
</div>
<div
class=
"mb-3 text-size-sm"
v-if=
"currentNode.attributes.default
Flow
"
>
其它条件不满足进入此分支(该分支不可编辑和删除)
</div>
<div
v-else
>
<el-form
label-position=
"top"
>
<el-form-item
label=
"
配置方式
"
prop=
"conditionType"
>
<el-form-item
label=
"
条件类型
"
prop=
"conditionType"
>
<el-radio-group
v-model=
"currentNode.attributes.conditionType"
@
change=
"changeConditionType"
...
...
@@ -33,7 +33,7 @@
</el-form-item>
<el-form-item
v-if=
"currentNode.attributes.conditionType ===
2
"
v-if=
"currentNode.attributes.conditionType ===
1
"
label=
"条件表达式"
prop=
"conditionExpression"
>
...
...
@@ -44,13 +44,13 @@
style=
"width: 100%"
/>
</el-form-item>
<el-form-item
<
!-- <
el-form-item
v-if="currentNode.attributes.conditionType === 1"
label="条件规则"
prop="conditionExpression"
>
<span class="text-red-400">待实现</span>
</el-form-item>
</el-form-item>
-->
</el-form>
</div>
</div>
...
...
@@ -93,17 +93,17 @@ const closeDrawer = () => {
}
// 保存配置
const
saveConfig
=
()
=>
{
if
(
!
currentNode
.
value
.
attributes
.
default
Condition
)
{
if
(
!
currentNode
.
value
.
attributes
.
default
Flow
)
{
currentNode
.
value
.
showText
=
getShowText
();
}
settingVisible
.
value
=
false
}
const
getShowText
=
()
:
string
=>
{
let
showText
=
''
;
// if (currentNode.value.attributes.conditionType === 1) {
// showText = '待实现'
// }
if
(
currentNode
.
value
.
attributes
.
conditionType
===
1
)
{
showText
=
'待实现'
}
if
(
currentNode
.
value
.
attributes
.
conditionType
===
2
)
{
if
(
currentNode
.
value
.
attributes
.
conditionExpression
)
{
showText
=
`表达式:
${
currentNode
.
value
.
attributes
.
conditionExpression
}
`
}
...
...
src/components/SimpleProcessDesignerV2/src/nodes/CopyTaskNode.vue
View file @
e8193a0a
...
...
@@ -28,7 +28,7 @@
</div>
<div
class=
"node-toolbar"
>
<!--
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:document-copy"
@
click=
"copyNode"
/></div>
-->
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:
circle-close"
:size=
"18
"
@
click=
"deleteNode"
/></div>
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:
delete"
:size=
"16
"
@
click=
"deleteNode"
/></div>
</div>
</div>
...
...
src/components/SimpleProcessDesignerV2/src/nodes/ExclusiveNode.vue
View file @
e8193a0a
...
...
@@ -2,11 +2,7 @@
<div
class=
"branch-node-wrapper"
>
<div
class=
"branch-node-container"
>
<div
class=
"branch-node-add"
@
click=
"addCondition"
>
添加条件
</div>
<div
class=
"branch-node-item"
v-for=
"(item, index) in currentNode.conditionNodes"
:key=
"index"
>
<div
class=
"branch-node-item"
v-for=
"(item, index) in currentNode.conditionNodes"
:key=
"index"
>
<template
v-if=
"index == 0"
>
<div
class=
"branch-line-first-top"
></div>
<div
class=
"branch-line-first-bottom"
></div>
...
...
@@ -17,31 +13,40 @@
</
template
>
<div
class=
"node-wrapper"
>
<div
class=
"node-container"
>
<div
class=
"node-box"
:class=
"{
'node-config-error': !item.showText
}"
>
<div
class=
"node-box"
:class=
"{
'node-config-error': !item.showText
}"
>
<div
class=
"branch-node-title-container"
>
<div
class=
"branch-title"
v-if=
"showInputs[index]"
>
<input
type=
"text"
class=
"input-max-width editable-title-input"
@
blur=
"blurEvent(index)"
v-mountedFocus
v-model=
"item.name"
/>
type=
"text"
class=
"input-max-width editable-title-input"
@
blur=
"blurEvent(index)"
v-mountedFocus
v-model=
"item.name"
/>
</div>
<div
v-else
class=
"branch-title"
@
click=
"clickEvent(index)"
>
{{ item.name }}
</div>
<div
class=
"branch-priority"
>
优先级{{ index + 1 }}
</div>
</div>
<div
class=
"node-content"
@
click=
"conditionNodeConfig(item.id)"
>
<div
class=
"
node-text"
:title=
"item.showText"
v-if
=
"item.showText"
>
<div
class=
"
branch-
node-content"
@
click=
"conditionNodeConfig(item.id)"
>
<div
class=
"
branch-node-text"
:title=
"item.showText"
v-if
=
"item.showText"
>
{{ item.showText }}
</div>
<div
class=
"
node-text"
v-else
>
<div
class=
"
branch-node-text"
v-else
>
{{ NODE_DEFAULT_TEXT.get(NodeType.CONDITION_NODE) }}
</div>
<Icon
icon=
"ep:arrow-right-bold"
/>
</div>
<div
class=
"node-toolbar"
v-if=
"index + 1 !== currentNode.conditionNodes?.length"
>
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:circle-close"
@
click=
"deleteCondition(index)"
/></div>
<div
class=
"toolbar-icon"
>
<Icon
icon=
"ep:delete"
:size=
"16"
@
click=
"deleteCondition(index)"
/>
</div>
</div>
<div
class=
"branch-node-move move-node-left"
v-if=
"index != 0 && index + 1 !== currentNode.conditionNodes?.length"
@
click=
"moveNode(index, -1)"
>
<Icon
icon=
"ep:arrow-left"
/>
</div>
<div
class=
"branch-node-move move-node-right"
v-if=
"currentNode.conditionNodes && index < currentNode.conditionNodes.length - 2"
@
click=
"moveNode(index, 1)"
>
<Icon
icon=
"ep:arrow-right"
/>
</div>
</div>
<NodeHandler
v-model:child-node=
"item.childNode"
/>
...
...
@@ -49,7 +54,7 @@
</div>
<ConditionNodeConfig
:condition-node=
"item"
:ref=
"item.id"
/>
<!-- 递归显示子节点 -->
<ProcessNodeTree
v-if=
"item && item.childNode"
v-model:flow-node=
"item.childNode"
/>
<ProcessNodeTree
v-if=
"item && item.childNode"
v-model:flow-node=
"item.childNode"
/>
</div>
</div>
<NodeHandler
v-if=
"currentNode"
v-model:child-node=
"currentNode.childNode"
/>
...
...
@@ -74,14 +79,14 @@ const props = defineProps({
})
// 定义事件,更新父组件
const
emits
=
defineEmits
<
{
'update:modelValue'
:
[
node
:
SimpleFlowNode
|
undefined
]
'update:modelValue'
:
[
node
:
SimpleFlowNode
|
undefined
]
}
>
()
const
currentNode
=
ref
<
SimpleFlowNode
>
(
props
.
flowNode
)
// const conditionNodes = computed(() => currentNode.value.conditionNodes);
watch
(()
=>
props
.
flowNode
,
(
newValue
)
=>
{
currentNode
.
value
=
newValue
;
watch
(()
=>
props
.
flowNode
,
(
newValue
)
=>
{
currentNode
.
value
=
newValue
;
});
// TODO 测试后续去掉
// watch(() => conditionNodes, (newValue) => {
...
...
@@ -90,17 +95,17 @@ watch(() => props.flowNode, (newValue) => {
const
showInputs
=
ref
<
boolean
[]
>
([])
// 失去焦点
const
blurEvent
=
(
index
:
number
)
=>
{
const
blurEvent
=
(
index
:
number
)
=>
{
showInputs
.
value
[
index
]
=
false
const
conditionNode
=
currentNode
.
value
.
conditionNodes
?.
at
(
index
)
as
SimpleFlowNode
;
conditionNode
.
name
=
conditionNode
.
name
||
'条件'
+
index
const
conditionNode
=
currentNode
.
value
.
conditionNodes
?.
at
(
index
)
as
SimpleFlowNode
;
conditionNode
.
name
=
conditionNode
.
name
||
'条件'
+
index
}
// 点击条件名称
const
clickEvent
=
(
index
:
number
)
=>
{
const
clickEvent
=
(
index
:
number
)
=>
{
showInputs
.
value
[
index
]
=
true
}
const
conditionNodeConfig
=
(
nodeId
:
string
)
=>
{
const
conditionNodeConfig
=
(
nodeId
:
string
)
=>
{
console
.
log
(
'nodeId'
,
nodeId
);
console
.
log
(
"proxy.$refs"
,
proxy
.
$refs
);
// TODO 测试后续去掉
...
...
@@ -109,29 +114,31 @@ const conditionNodeConfig = (nodeId:string) => {
conditionNode
.
open
()
}
// 新增条件
const
addCondition
=
()
=>
{
const
conditionNodes
=
currentNode
.
value
.
conditionNodes
;
const
conditionNodes
=
currentNode
.
value
.
conditionNodes
;
if
(
conditionNodes
)
{
const
len
=
conditionNodes
.
length
let
lastIndex
=
len
-
1
const
conditionData
:
SimpleFlowNode
=
{
id
:
generateUUID
(),
name
:
'条件'
+
len
,
showText
:
''
,
id
:
'Flow_'
+
generateUUID
(),
name
:
'条件'
+
len
,
showText
:
''
,
type
:
NodeType
.
CONDITION_NODE
,
childNode
:
undefined
,
conditionNodes
:
[],
attributes
:
{
conditionType
:
1
,
default
Condition
:
false
default
Flow
:
false
}
}
conditionNodes
.
splice
(
lastIndex
,
0
,
conditionData
)
}
}
const
deleteCondition
=
(
index
:
number
)
=>
{
const
conditionNodes
=
currentNode
.
value
.
conditionNodes
;
// 删除条件
const
deleteCondition
=
(
index
:
number
)
=>
{
const
conditionNodes
=
currentNode
.
value
.
conditionNodes
;
if
(
conditionNodes
)
{
conditionNodes
.
splice
(
index
,
1
)
if
(
conditionNodes
.
length
==
1
)
{
...
...
@@ -142,6 +149,17 @@ const deleteCondition = (index:number) => {
}
}
// 移动节点
const
moveNode
=
(
index
:
number
,
to
:
number
)
=>
{
// -1 :向左 1: 向右
if
(
currentNode
.
value
.
conditionNodes
)
{
currentNode
.
value
.
conditionNodes
[
index
]
=
currentNode
.
value
.
conditionNodes
.
splice
(
index
+
to
,
1
,
currentNode
.
value
.
conditionNodes
[
index
])[
0
]
}
}
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
src/components/SimpleProcessDesignerV2/src/nodes/UserTaskNode.vue
View file @
e8193a0a
...
...
@@ -28,7 +28,7 @@
</div>
<div
class=
"node-toolbar"
>
<!--
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:document-copy"
@
click=
"copyNode"
/></div>
-->
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:
circle-clos
e"
:size=
"18"
@
click=
"deleteNode"
/></div>
<div
class=
"toolbar-icon"
><Icon
icon=
"ep:
delet
e"
:size=
"18"
@
click=
"deleteNode"
/></div>
</div>
</div>
<!-- 传递子节点给添加节点组件。会在子节点前面添加节点 -->
...
...
src/components/SimpleProcessDesignerV2/theme/simple-process-designer.scss
View file @
e8193a0a
...
...
@@ -95,6 +95,10 @@
.node-toolbar
{
opacity
:
1
;
}
.branch-node-move
{
display
:
flex
;
}
}
// 普通节点标题
...
...
@@ -181,24 +185,74 @@
}
}
//条件节点内容
.branch-node-content
{
display
:
flex
;
min-height
:
32px
;
padding
:
4px
8px
;
margin-top
:
4px
;
line-height
:
32px
;
align-items
:
center
;
color
:
#111f2c
;
border-radius
:
4px
;
.branch-node-text
{
overflow
:
hidden
;
font-size
:
14px
;
line-height
:
24px
;
text-overflow
:
ellipsis
;
word-break
:
break-all
;
-webkit-line-clamp
:
2
;
/* 这将限制文本显示为两行 */
-webkit-box-orient
:
vertical
;
}
}
// 节点操作 :删除
.node-toolbar
{
opacity
:
0
;
position
:
absolute
;
top
:
-5px
;
right
:
-8
px
;
top
:
-
2
5px
;
right
:
0
px
;
display
:
flex
;
.toolbar-icon
{
text-align
:
center
;
vertical-align
:
middle
;
color
:
#6d6c6e
;
color
:
#000
;
}
}
// 条件节点左右移动
.branch-node-move
{
position
:
absolute
;
width
:
10px
;
cursor
:
pointer
;
display
:
none
;
align-items
:
center
;
height
:
100%
;
justify-content
:
center
;
}
.move-node-left
{
left
:
-2px
;
top
:
0px
;
background
:
rgba
(
126
,
134
,
142
,
.08
);
border-top-left-radius
:
8px
;
border-bottom-left-radius
:
8px
;
}
.move-node-right
{
right
:
-2px
;
top
:
0px
;
background
:
rgba
(
126
,
134
,
142
,.
08
);
border-top-right-radius
:
6px
;
border-bottom-right-radius
:
6px
;
}
}
.node-config-error
{
border-color
:
#ff5219
;
border-color
:
#ff5219
!
important
;
}
// 普通节点包装
.node-wrapper
{
...
...
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