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
07dc7258
authored
Mar 20, 2024
by
jason
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
整合仿钉钉流程设计器
https://github.com/StavinLi/Workflow-Vue3
parent
d16194b7
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
2330 additions
and
0 deletions
+2330
-0
src/components/SimpleProcessDesigner/src/addNode.vue
+237
-0
src/components/SimpleProcessDesigner/src/drawer/approverDrawer.vue
+283
-0
src/components/SimpleProcessDesigner/src/nodeWrap.vue
+298
-0
src/components/SimpleProcessDesigner/src/util.ts
+165
-0
src/components/SimpleProcessDesigner/theme/workflow.css
+1292
-0
src/store/modules/simpleWorkflow.ts
+55
-0
No files found.
src/components/SimpleProcessDesigner/src/addNode.vue
0 → 100644
View file @
07dc7258
/* 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"
>
</span>
</div>
<p>
审批人
</p>
</a>
<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>
</div>
<template
#
reference
>
<button
class=
"btn"
type=
"button"
>
<span
class=
"iconfont"
>
</span>
</button>
</
template
>
</el-popover>
</div>
</div>
</template>
<
script
setup
>
import
{
ref
}
from
'vue'
let
props
=
defineProps
({
childNodeP
:
{
type
:
Object
,
default
:
()
=>
({})
}
})
let
emits
=
defineEmits
([
'update:childNodeP'
])
let
visible
=
ref
(
false
)
const
addType
=
(
type
)
=>
{
visible
.
value
=
false
if
(
type
!=
4
)
{
var
data
if
(
type
==
1
)
{
data
=
{
nodeName
:
'审核人'
,
error
:
true
,
type
:
1
,
settype
:
1
,
selectMode
:
0
,
selectRange
:
0
,
directorLevel
:
1
,
examineMode
:
1
,
noHanderAction
:
1
,
examineEndDirectorLevel
:
0
,
childNode
:
props
.
childNodeP
,
nodeUserList
:
[]
}
}
else
if
(
type
==
2
)
{
data
=
{
nodeName
:
'抄送人'
,
type
:
2
,
ccSelfSelectFlag
:
1
,
childNode
:
props
.
childNodeP
,
nodeUserList
:
[]
}
}
emits
(
'update:childNodeP'
,
data
)
}
else
{
emits
(
'update:childNodeP'
,
{
nodeName
:
'路由'
,
type
:
4
,
childNode
:
null
,
conditionNodes
:
[
{
nodeName
:
'条件1'
,
error
:
true
,
type
:
3
,
priorityLevel
:
1
,
conditionList
:
[],
nodeUserList
:
[],
childNode
:
props
.
childNodeP
},
{
nodeName
:
'条件2'
,
type
:
3
,
priorityLevel
:
2
,
conditionList
:
[],
nodeUserList
:
[],
childNode
:
null
}
]
})
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
.add-node-btn-box
{
width
:
240px
;
display
:
inline-flex
;
-ms-flex-negative
:
0
;
flex-shrink
:
0
;
-webkit-box-flex
:
1
;
-ms-flex-positive
:
1
;
position
:
relative
;
&:before
{
content
:
''
;
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
z-index
:
-1
;
margin
:
auto
;
width
:
2px
;
height
:
100%
;
background-color
:
#cacaca
;
}
.add-node-btn
{
user-select
:
none
;
width
:
240px
;
padding
:
20px
0
32px
;
display
:
flex
;
-webkit-box-pack
:
center
;
justify-content
:
center
;
flex-shrink
:
0
;
-webkit-box-flex
:
1
;
flex-grow
:
1
;
.btn
{
outline
:
none
;
box-shadow
:
0
2px
4px
0
rgba
(
0
,
0
,
0
,
0.1
);
width
:
30px
;
height
:
30px
;
background
:
#3296fa
;
border-radius
:
50%
;
position
:
relative
;
border
:
none
;
line-height
:
30px
;
-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
);
.iconfont
{
color
:
#fff
;
font-size
:
16px
;
}
&
:hover
{
transform
:
scale
(
1.3
);
box-shadow
:
0
13px
27px
0
rgba
(
0
,
0
,
0
,
0.1
);
}
&
:active
{
transform
:
none
;
background
:
#1e83e9
;
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
{
user-select
:
none
;
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
);
.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
{
box-shadow
:
none
;
background
:
#eaeaea
;
}
.iconfont
{
color
:
inherit
;
}
}
}
}
</
style
>
src/components/SimpleProcessDesigner/src/drawer/approverDrawer.vue
0 → 100644
View file @
07dc7258
<
template
>
<el-drawer
:append-to-body=
"true"
title=
"审批人设置"
v-model=
"visible"
class=
"set_promoter"
:show-close=
"false"
:size=
"550"
:before-close=
"saveApprover"
>
<div
class=
"demo-drawer__content"
>
<div
class=
"drawer_content"
>
<div
class=
"approver_content"
>
<el-radio-group
v-model=
"approverConfig.settype"
class=
"clear"
@
change=
"changeType"
>
<el-radio
v-for=
"
{ value, label } in setTypes" :key="value" :label="value">
{{
label
}}
</el-radio>
</el-radio-group>
<el-button
type=
"primary"
@
click=
"addApprover"
v-if=
"approverConfig.settype == 1"
>
添加/修改成员
</el-button
>
<p
class=
"selected_list"
v-if=
"approverConfig.settype == 1"
>
<span
v-for=
"(item, index) in approverConfig.nodeUserList"
:key=
"index"
>
{{
item
.
name
}}
<img
src=
"@/assets/images/add-close1.png"
@
click=
"removeEle(approverConfig.nodeUserList, item, 'targetId')"
/>
</span>
<a
v-if=
"approverConfig.nodeUserList.length != 0"
@
click=
"approverConfig.nodeUserList = []"
>
清除
</a
>
</p>
</div>
<div
class=
"approver_manager"
v-if=
"approverConfig.settype == 2"
>
<p>
<span>
发起人的:
</span>
<select
v-model=
"approverConfig.directorLevel"
>
<option
v-for=
"item in directorMaxLevel"
:value=
"item"
:key=
"item"
>
{{
item
==
1
?
'直接'
:
'第'
+
item
+
'级'
}}
主管
</option
>
</select>
</p>
<p
class=
"tip"
>
找不到主管时,由上级主管代审批
</p>
</div>
<div
class=
"approver_self"
v-if=
"approverConfig.settype == 5"
>
<p>
该审批节点设置“发起人自己”后,审批人默认为发起人
</p>
</div>
<div
class=
"approver_self_select"
v-show=
"approverConfig.settype == 4"
>
<el-radio-group
v-model=
"approverConfig.selectMode"
style=
"width: 100%"
>
<el-radio
v-for=
"
{ value, label } in selectModes" :label="value" :key="value">
{{
label
}}
</el-radio>
</el-radio-group>
<h3>
选择范围
</h3>
<el-radio-group
v-model=
"approverConfig.selectRange"
style=
"width: 100%"
@
change=
"changeRange"
>
<el-radio
v-for=
"
{ value, label } in selectRanges" :label="value" :key="value">
{{
label
}}
</el-radio>
</el-radio-group>
<template
v-if=
"approverConfig.selectRange == 2 || approverConfig.selectRange == 3"
>
<el-button
type=
"primary"
@
click=
"addApprover"
v-if=
"approverConfig.selectRange == 2"
>
添加/修改成员
</el-button
>
<el-button
type=
"primary"
@
click=
"addRoleApprover"
v-else
>
添加/修改角色
</el-button>
<p
class=
"selected_list"
>
<span
v-for=
"(item, index) in approverConfig.nodeUserList"
:key=
"index"
>
{{
item
.
name
}}
<img
src=
"@/assets/images/add-close1.png"
@
click=
"removeEle(approverConfig.nodeUserList, item, 'targetId')"
/>
</span>
<a
v-if=
"approverConfig.nodeUserList.length != 0 && approverConfig.selectRange != 1"
@
click=
"approverConfig.nodeUserList = []"
>
清除
</a
>
</p>
</
template
>
</div>
<div
class=
"approver_manager"
v-if=
"approverConfig.settype == 7"
>
<p>
审批终点
</p>
<p
style=
"padding-bottom: 20px"
>
<span>
发起人的:
</span>
<select
v-model=
"approverConfig.examineEndDirectorLevel"
>
<option
v-for=
"item in directorMaxLevel"
:value=
"item"
:key=
"item"
>
{{ item == 1 ? '最高' : '第' + item }}层级主管
</option
>
</select>
</p>
</div>
<div
class=
"approver_some"
v-if=
"
(approverConfig.settype == 1 && approverConfig.nodeUserList.length > 1) ||
approverConfig.settype == 2 ||
(approverConfig.settype == 4 && approverConfig.selectMode == 2)
"
>
<p>
多人审批时采用的审批方式
</p>
<el-radio-group
v-model=
"approverConfig.examineMode"
class=
"clear"
>
<el-radio
:label=
"1"
>
依次审批
</el-radio>
<br
/>
<el-radio
:label=
"2"
v-if=
"approverConfig.settype != 2"
>
会签(须所有审批人同意)
</el-radio
>
</el-radio-group>
</div>
<div
class=
"approver_some"
v-if=
"approverConfig.settype == 2 || approverConfig.settype == 7"
>
<p>
审批人为空时
</p>
<el-radio-group
v-model=
"approverConfig.noHanderAction"
class=
"clear"
>
<el-radio
:label=
"1"
>
自动审批通过/不允许发起
</el-radio>
<br
/>
<el-radio
:label=
"2"
>
转交给审核管理员
</el-radio>
</el-radio-group>
</div>
</div>
<div
class=
"demo-drawer__footer clear"
>
<el-button
type=
"primary"
@
click=
"saveApprover"
>
确 定
</el-button>
<el-button
@
click=
"closeDrawer"
>
取 消
</el-button>
</div>
</div>
</el-drawer>
</template>
<
script
lang=
"ts"
setup
>
import
{
ref
,
watch
,
computed
}
from
'vue'
import
{
useWorkFlowStoreWithOut
}
from
'@/store/modules/simpleWorkflow'
import
{
setTypes
,
selectModes
,
selectRanges
}
from
'../util'
import
{
removeEle
,
setApproverStr
}
from
'../util'
let
props
=
defineProps
({
directorMaxLevel
:
{
type
:
Number
,
default
:
0
}
})
let
approverConfig
=
ref
({})
let
approverVisible
=
ref
(
false
)
let
approverRoleVisible
=
ref
(
false
)
let
checkedRoleList
=
ref
([])
let
checkedList
=
ref
([])
let
store
=
useWorkFlowStoreWithOut
()
let
{
setApproverConfig
,
setApprover
}
=
store
let
approverConfig1
=
computed
(()
=>
store
.
approverConfig1
)
let
approverDrawer
=
computed
(()
=>
store
.
approverDrawer
)
let
visible
=
computed
({
get
()
{
return
approverDrawer
.
value
},
set
()
{
closeDrawer
()
}
})
watch
(
approverConfig1
,
(
val
:
any
)
=>
{
approverConfig
.
value
=
val
.
value
})
let
changeRange
=
()
=>
{
approverConfig
.
value
.
nodeUserList
=
[]
}
const
changeType
=
(
val
)
=>
{
approverConfig
.
value
.
nodeUserList
=
[]
approverConfig
.
value
.
examineMode
=
1
approverConfig
.
value
.
noHanderAction
=
2
if
(
val
==
2
)
{
approverConfig
.
value
.
directorLevel
=
1
}
else
if
(
val
==
4
)
{
approverConfig
.
value
.
selectMode
=
1
approverConfig
.
value
.
selectRange
=
1
}
else
if
(
val
==
7
)
{
approverConfig
.
value
.
examineEndDirectorLevel
=
1
}
}
const
addApprover
=
()
=>
{
approverVisible
.
value
=
true
checkedList
.
value
=
approverConfig
.
value
.
nodeUserList
}
const
addRoleApprover
=
()
=>
{
approverRoleVisible
.
value
=
true
checkedRoleList
.
value
=
approverConfig
.
value
.
nodeUserList
}
const
sureApprover
=
(
data
)
=>
{
approverConfig
.
value
.
nodeUserList
=
data
approverVisible
.
value
=
false
}
const
sureRoleApprover
=
(
data
)
=>
{
approverConfig
.
value
.
nodeUserList
=
data
approverRoleVisible
.
value
=
false
}
const
saveApprover
=
()
=>
{
approverConfig
.
value
.
error
=
!
setApproverStr
(
approverConfig
.
value
)
setApproverConfig
({
value
:
approverConfig
.
value
,
flag
:
true
,
id
:
approverConfig1
.
value
.
id
})
closeDrawer
()
}
const
closeDrawer
=
()
=>
{
setApprover
(
false
)
}
</
script
>
<
style
lang=
"scss"
scoped
>
.set_promoter
{
.approver_content
{
padding-bottom
:
10px
;
border-bottom
:
1px
solid
#f2f2f2
;
}
.approver_self_select
,
.approver_content
{
.el-button
{
margin-bottom
:
20px
;
}
}
.approver_content
,
.approver_some
,
.approver_self_select
{
.el-radio-group
{
display
:
unset
;
}
.el-radio
{
width
:
27%
;
margin-bottom
:
20px
;
height
:
16px
;
}
}
.approver_manager
p
{
line-height
:
32px
;
}
.approver_manager
select
{
width
:
420px
;
height
:
32px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
border-radius
:
4px
;
border
:
1px
solid
rgba
(
217
,
217
,
217
,
1
);
}
.approver_manager
p
.tip
{
margin
:
10px
0
22px
0
;
font-size
:
12px
;
line-height
:
16px
;
color
:
#f8642d
;
}
.approver_self
{
padding
:
28px
20px
;
}
.approver_self_select
,
.approver_manager
,
.approver_content
,
.approver_some
{
padding
:
20px
20px
0
;
}
.approver_manager
p
:first-of-type
,
.approver_some
p
{
line-height
:
19px
;
font-size
:
14px
;
margin-bottom
:
14px
;
}
.approver_self_select
h3
{
margin
:
5px
0
20px
;
font-size
:
14px
;
font-weight
:
bold
;
line-height
:
19px
;
}
}
</
style
>
src/components/SimpleProcessDesigner/src/nodeWrap.vue
0 → 100644
View file @
07dc7258
<!-- 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=
"(nodeConfig.type == 0 ? 'start-node ' : '') +(isTried && nodeConfig.error ? 'active error' : '')"
>
<div
class=
"title"
:style=
"`background: rgb($
{bgColors[nodeConfig.type]});`">
<span
v-if=
"nodeConfig.type == 0"
>
{{
nodeConfig
.
nodeName
}}
</span>
<template
v-else
>
<span
class=
"iconfont"
>
{{
nodeConfig
.
type
==
1
?
''
:
''
}}
</span>
<input
v-if=
"isInput"
type=
"text"
class=
"ant-input editable-title-input"
@
blur=
"blurEvent()"
@
focus=
"$event.currentTarget.select()"
v-focus
v-model=
"nodeConfig.nodeName"
:placeholder=
"defaultText"
/>
<span
v-else
class=
"editable-title"
@
click=
"clickEvent()"
>
{{
nodeConfig
.
nodeName
}}
</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>
{{showText}}
</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"
>
添加条件
</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=
"auto-judge"
:class=
"isTried && item.error ? 'error active' : ''"
>
<div
class=
"sort-left"
v-if=
"index != 0"
@
click=
"arrTransfer(index, -1)"
>
<
</div>
<div
class=
"title-wrapper"
>
<input
v-if=
"isInputList[index]"
type=
"text"
class=
"ant-input editable-title-input"
@
blur=
"blurEvent(index)"
@
focus=
"$event.currentTarget.select()"
v-focus
v-model=
"item.nodeName"
/>
<span
v-else
class=
"editable-title"
@
click=
"clickEvent(index)"
>
{{ item.nodeName }}
</span>
<span
class=
"priority-title"
@
click=
"setPerson(item.priorityLevel)"
>
优先级{{ item.priorityLevel }}
</span>
<i
class=
"anticon anticon-close close"
@
click=
"delTerm(index)"
></i>
</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=
"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>
<nodeWrap
v-if=
"nodeConfig.childNode"
v-model:nodeConfig=
"nodeConfig.childNode"
/>
</template>
<
script
setup
>
import
addNode
from
'./addNode.vue'
import
{
onMounted
,
ref
,
watch
,
getCurrentInstance
,
computed
}
from
'vue'
import
{
arrToStr
,
conditionStr
,
setApproverStr
,
copyerStr
,
bgColors
,
placeholderList
}
from
'./util'
import
{
useWorkFlowStoreWithOut
}
from
'@/store/modules/simpleWorkflow'
let
_uid
=
getCurrentInstance
().
uid
let
props
=
defineProps
({
nodeConfig
:
{
type
:
Object
,
default
:
()
=>
({})
},
flowPermission
:
{
type
:
Object
,
// eslint-disable-next-line vue/require-valid-default-prop
default
:
()
=>
[]
}
})
let
defaultText
=
computed
(()
=>
{
return
placeholderList
[
props
.
nodeConfig
.
type
]
})
let
showText
=
computed
(()
=>
{
if
(
props
.
nodeConfig
.
type
==
0
)
return
arrToStr
(
props
.
flowPermission
)
||
'所有人'
if
(
props
.
nodeConfig
.
type
==
1
)
return
setApproverStr
(
props
.
nodeConfig
)
return
copyerStr
(
props
.
nodeConfig
)
})
let
isInputList
=
ref
([])
let
isInput
=
ref
(
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:flowPermission'
,
'update:nodeConfig'
])
let
store
=
useWorkFlowStoreWithOut
()
let
{
setPromoter
,
setApprover
,
setCopyer
,
setCondition
,
setFlowPermission
,
setApproverConfig
,
setCopyerConfig
,
setConditionsConfig
}
=
store
let
isTried
=
computed
(()
=>
store
.
isTried
)
let
flowPermission1
=
computed
(()
=>
store
.
flowPermission1
)
let
approverConfig1
=
computed
(()
=>
store
.
approverConfig1
)
let
copyerConfig1
=
computed
(()
=>
store
.
copyerConfig1
)
let
conditionsConfig1
=
computed
(()
=>
store
.
conditionsConfig1
)
watch
(
flowPermission1
,
(
flow
)
=>
{
if
(
flow
.
flag
&&
flow
.
id
===
_uid
)
{
emits
(
'update:flowPermission'
,
flow
.
value
)
}
})
watch
(
approverConfig1
,
(
approver
)
=>
{
if
(
approver
.
flag
&&
approver
.
id
===
_uid
)
{
emits
(
'update:nodeConfig'
,
approver
.
value
)
}
})
watch
(
copyerConfig1
,
(
copyer
)
=>
{
if
(
copyer
.
flag
&&
copyer
.
id
===
_uid
)
{
emits
(
'update:nodeConfig'
,
copyer
.
value
)
}
})
watch
(
conditionsConfig1
,
(
condition
)
=>
{
if
(
condition
.
flag
&&
condition
.
id
===
_uid
)
{
emits
(
'update:nodeConfig'
,
condition
.
value
)
}
})
const
clickEvent
=
(
index
)
=>
{
if
(
index
||
index
===
0
)
{
isInputList
.
value
[
index
]
=
true
}
else
{
isInput
.
value
=
true
}
}
const
blurEvent
=
(
index
)
=>
{
if
(
index
||
index
===
0
)
{
isInputList
.
value
[
index
]
=
false
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
[
index
].
nodeName
=
props
.
nodeConfig
.
conditionNodes
[
index
].
nodeName
||
'条件'
}
else
{
isInput
.
value
=
false
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
nodeName
=
props
.
nodeConfig
.
nodeName
||
defaultText
}
}
const
delNode
=
()
=>
{
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
.
childNode
)
}
const
addTerm
=
()
=>
{
let
len
=
props
.
nodeConfig
.
conditionNodes
.
length
+
1
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
.
push
({
nodeName
:
'条件'
+
len
,
type
:
3
,
priorityLevel
:
len
,
conditionList
:
[],
nodeUserList
:
[],
childNode
:
null
})
resetConditionNodesErr
()
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
)
}
const
delTerm
=
(
index
)
=>
{
// eslint-disable-next-line vue/no-mutating-props
props
.
nodeConfig
.
conditionNodes
.
splice
(
index
,
1
)
props
.
nodeConfig
.
conditionNodes
.
map
((
item
,
index
)
=>
{
item
.
priorityLevel
=
index
+
1
item
.
nodeName
=
`条件
${
index
+
1
}
`
})
resetConditionNodesErr
()
emits
(
'update:nodeConfig'
,
props
.
nodeConfig
)
if
(
props
.
nodeConfig
.
conditionNodes
.
length
==
1
)
{
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
)
=>
{
var
{
type
}
=
props
.
nodeConfig
if
(
type
==
0
)
{
setPromoter
(
true
)
setFlowPermission
({
value
:
props
.
flowPermission
,
flag
:
false
,
id
:
_uid
})
}
else
if
(
type
==
1
)
{
setApprover
(
true
)
setApproverConfig
({
value
:
{
...
JSON
.
parse
(
JSON
.
stringify
(
props
.
nodeConfig
)),
...{
settype
:
props
.
nodeConfig
.
settype
?
props
.
nodeConfig
.
settype
:
1
}
},
flag
:
false
,
id
:
_uid
})
}
else
if
(
type
==
2
)
{
setCopyer
(
true
)
setCopyerConfig
({
value
:
JSON
.
parse
(
JSON
.
stringify
(
props
.
nodeConfig
)),
flag
:
false
,
id
:
_uid
})
}
else
{
setCondition
(
true
)
setConditionsConfig
({
value
:
JSON
.
parse
(
JSON
.
stringify
(
props
.
nodeConfig
)),
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
>
src/components/SimpleProcessDesigner/src/util.ts
0 → 100644
View file @
07dc7258
/**
* 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
copyerStr
=
(
nodeConfig
:
any
)
=>
{
if
(
nodeConfig
.
nodeUserList
.
length
!=
0
)
{
return
arrToStr
(
nodeConfig
.
nodeUserList
)
}
else
{
if
(
nodeConfig
.
ccSelfSelectFlag
==
1
)
{
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
?
'其他条件进入此流程'
:
'请设置条件'
}
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
}
并且 `
}
}
}
return
str
?
str
.
substring
(
0
,
str
.
length
-
4
)
:
'请设置条件'
}
}
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'
]
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/workflow.css
0 → 100644
View file @
07dc7258
.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
}
.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.active
.close
,
.dingflow-design
.auto-judge
:active
.close
,
.dingflow-design
.auto-judge
:hover
.close
{
display
:
block
}
.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
;
line-height
:
16px
}
.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
.close
{
display
:
none
;
position
:
absolute
;
right
:
-10px
;
top
:
-10px
;
width
:
20px
;
height
:
20px
;
font-size
:
14px
;
color
:
rgba
(
0
,
0
,
0
,
.25
);
border-radius
:
50%
;
text-align
:
center
;
line-height
:
20px
;
z-index
:
2
}
.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/store/modules/simpleWorkflow.ts
0 → 100644
View file @
07dc7258
import
{
store
}
from
'../index'
import
{
defineStore
}
from
'pinia'
export
const
useWorkFlowStore
=
defineStore
(
'simpleWorkflow'
,
{
state
:
()
=>
({
tableId
:
''
,
isTried
:
false
,
promoterDrawer
:
false
,
flowPermission1
:
{},
approverDrawer
:
false
,
approverConfig1
:
{},
copyerDrawer
:
false
,
copyerConfig1
:
{},
conditionDrawer
:
false
,
conditionsConfig1
:
{
conditionNodes
:
[]
}
}),
actions
:
{
setTableId
(
payload
)
{
this
.
tableId
=
payload
},
setIsTried
(
payload
)
{
this
.
isTried
=
payload
},
setPromoter
(
payload
)
{
this
.
promoterDrawer
=
payload
},
setFlowPermission
(
payload
)
{
this
.
flowPermission1
=
payload
},
setApprover
(
payload
)
{
this
.
approverDrawer
=
payload
},
setApproverConfig
(
payload
)
{
this
.
approverConfig1
=
payload
},
setCopyer
(
payload
)
{
this
.
copyerDrawer
=
payload
},
setCopyerConfig
(
payload
)
{
this
.
copyerConfig1
=
payload
},
setCondition
(
payload
)
{
this
.
conditionDrawer
=
payload
},
setConditionsConfig
(
payload
)
{
this
.
conditionsConfig1
=
payload
}
}
})
export
const
useWorkFlowStoreWithOut
=
()
=>
{
return
useWorkFlowStore
(
store
)
}
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