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
Unverified
Commit
9685fbf8
authored
Dec 15, 2024
by
芋道源码
Committed by
GitHub
Dec 15, 2024
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #111 from GoldenZqqq/feature/bpm
工作流模块改造优化
parents
24e13749
746aeaff
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1179 additions
and
161 deletions
+1179
-161
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
+72
-23
src/components/UserSelectForm/index.vue
+29
-10
src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue
+76
-39
src/router/modules/remaining.ts
+12
-0
src/views/bpm/model/CategoryDraggableModel.vue
+22
-17
src/views/bpm/model/CreateUpdate.vue
+644
-0
src/views/bpm/model/ModelForm.vue
+155
-19
src/views/bpm/model/editor/index.vue
+136
-46
src/views/bpm/model/index.vue
+6
-1
src/views/bpm/simple/SimpleModelDesign.vue
+27
-6
No files found.
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
View file @
9685fbf8
...
@@ -38,12 +38,21 @@ import * as UserGroupApi from '@/api/bpm/userGroup'
...
@@ -38,12 +38,21 @@ import * as UserGroupApi from '@/api/bpm/userGroup'
defineOptions
({
defineOptions
({
name
:
'SimpleProcessDesigner'
name
:
'SimpleProcessDesigner'
})
})
const
emits
=
defineEmits
([
'success'
])
// 保存成功事件
const
emits
=
defineEmits
([
'success'
])
// 保存成功事件
const
props
=
defineProps
({
const
props
=
defineProps
({
modelId
:
{
modelId
:
{
type
:
String
,
type
:
String
,
required
:
true
required
:
false
},
modelKey
:
{
type
:
String
,
required
:
false
},
modelName
:
{
type
:
String
,
required
:
false
}
}
})
})
...
@@ -69,6 +78,33 @@ const message = useMessage() // 国际化
...
@@ -69,6 +78,33 @@ const message = useMessage() // 国际化
const
processNodeTree
=
ref
<
SimpleFlowNode
|
undefined
>
()
const
processNodeTree
=
ref
<
SimpleFlowNode
|
undefined
>
()
const
errorDialogVisible
=
ref
(
false
)
const
errorDialogVisible
=
ref
(
false
)
let
errorNodes
:
SimpleFlowNode
[]
=
[]
let
errorNodes
:
SimpleFlowNode
[]
=
[]
// 添加更新模型的方法
const
updateModel
=
(
key
?:
string
,
name
?:
string
)
=>
{
if
(
!
processNodeTree
.
value
)
{
processNodeTree
.
value
=
{
name
:
name
||
'发起人'
,
type
:
NodeType
.
START_USER_NODE
,
id
:
NodeId
.
START_USER_NODE_ID
,
childNode
:
{
id
:
NodeId
.
END_EVENT_NODE_ID
,
name
:
'结束'
,
type
:
NodeType
.
END_EVENT_NODE
}
}
}
else
if
(
name
)
{
// 更新现有模型的名称
processNodeTree
.
value
.
name
=
name
}
}
// 监听属性变化
watch
([()
=>
props
.
modelKey
,
()
=>
props
.
modelName
],
([
newKey
,
newName
])
=>
{
if
(
!
props
.
modelId
&&
newKey
&&
newName
)
{
updateModel
(
newKey
,
newName
)
}
},
{
immediate
:
true
,
deep
:
true
})
const
saveSimpleFlowModel
=
async
(
simpleModelNode
:
SimpleFlowNode
)
=>
{
const
saveSimpleFlowModel
=
async
(
simpleModelNode
:
SimpleFlowNode
)
=>
{
if
(
!
simpleModelNode
)
{
if
(
!
simpleModelNode
)
{
message
.
error
(
'模型数据为空'
)
message
.
error
(
'模型数据为空'
)
...
@@ -76,21 +112,28 @@ const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
...
@@ -76,21 +112,28 @@ const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
}
}
try
{
try
{
loading
.
value
=
true
loading
.
value
=
true
const
data
=
{
if
(
props
.
modelId
)
{
id
:
props
.
modelId
,
// 编辑模式
simpleModel
:
simpleModelNode
const
data
=
{
}
id
:
props
.
modelId
,
const
result
=
await
updateBpmSimpleModel
(
data
)
simpleModel
:
simpleModelNode
if
(
result
)
{
}
message
.
success
(
'修改成功'
)
const
result
=
await
updateBpmSimpleModel
(
data
)
emits
(
'success'
)
if
(
result
)
{
message
.
success
(
'修改成功'
)
emits
(
'success'
)
}
else
{
message
.
alert
(
'修改失败'
)
}
}
else
{
}
else
{
message
.
alert
(
'修改失败'
)
// 新建模式,直接返回数据
emits
(
'success'
,
simpleModelNode
)
}
}
}
finally
{
}
finally
{
loading
.
value
=
false
loading
.
value
=
false
}
}
}
}
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
const
validateNode
=
(
node
:
SimpleFlowNode
|
undefined
,
errorNodes
:
SimpleFlowNode
[])
=>
{
const
validateNode
=
(
node
:
SimpleFlowNode
|
undefined
,
errorNodes
:
SimpleFlowNode
[])
=>
{
if
(
node
)
{
if
(
node
)
{
...
@@ -134,12 +177,14 @@ onMounted(async () => {
...
@@ -134,12 +177,14 @@ onMounted(async () => {
try
{
try
{
loading
.
value
=
true
loading
.
value
=
true
// 获取表单字段
// 获取表单字段
const
bpmnModel
=
await
getModel
(
props
.
modelId
)
if
(
props
.
modelId
)
{
if
(
bpmnModel
)
{
const
bpmnModel
=
await
getModel
(
props
.
modelId
)
formType
.
value
=
bpmnModel
.
formType
if
(
bpmnModel
)
{
if
(
formType
.
value
===
10
)
{
formType
.
value
=
bpmnModel
.
formType
const
bpmnForm
=
(
await
getForm
(
bpmnModel
.
formId
))
as
unknown
as
FormVO
if
(
formType
.
value
===
10
)
{
formFields
.
value
=
bpmnForm
?.
fields
const
bpmnForm
=
(
await
getForm
(
bpmnModel
.
formId
))
as
unknown
as
FormVO
formFields
.
value
=
bpmnForm
?.
fields
}
}
}
}
}
// 获得角色列表
// 获得角色列表
...
@@ -155,14 +200,18 @@ onMounted(async () => {
...
@@ -155,14 +200,18 @@ onMounted(async () => {
// 获取用户组列表
// 获取用户组列表
userGroupOptions
.
value
=
await
UserGroupApi
.
getUserGroupSimpleList
()
userGroupOptions
.
value
=
await
UserGroupApi
.
getUserGroupSimpleList
()
//获取 SIMPLE 设计器模型
if
(
props
.
modelId
)
{
const
result
=
await
getBpmSimpleModel
(
props
.
modelId
)
//获取 SIMPLE 设计器模型
if
(
result
)
{
const
result
=
await
getBpmSimpleModel
(
props
.
modelId
)
processNodeTree
.
value
=
result
if
(
result
)
{
}
else
{
processNodeTree
.
value
=
result
// 初始值
}
}
// 如果没有现有模型,创建初始模型
if
(
!
processNodeTree
.
value
)
{
processNodeTree
.
value
=
{
processNodeTree
.
value
=
{
name
:
'发起人'
,
name
:
props
.
modelName
||
'发起人'
,
type
:
NodeType
.
START_USER_NODE
,
type
:
NodeType
.
START_USER_NODE
,
id
:
NodeId
.
START_USER_NODE_ID
,
id
:
NodeId
.
START_USER_NODE_ID
,
childNode
:
{
childNode
:
{
...
...
src/components/UserSelectForm/index.vue
View file @
9685fbf8
...
@@ -39,7 +39,7 @@
...
@@ -39,7 +39,7 @@
</Dialog>
</Dialog>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
defaultProps
,
findTreeNode
,
handleTree
}
from
'@/utils/tree'
import
{
defaultProps
,
handleTree
}
from
'@/utils/tree'
import
*
as
DeptApi
from
'@/api/system/dept'
import
*
as
DeptApi
from
'@/api/system/dept'
import
*
as
UserApi
from
'@/api/system/user'
import
*
as
UserApi
from
'@/api/system/user'
...
@@ -50,6 +50,7 @@ const emit = defineEmits<{
...
@@ -50,6 +50,7 @@ const emit = defineEmits<{
const
{
t
}
=
useI18n
()
// 国际
const
{
t
}
=
useI18n
()
// 国际
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
const
deptTree
=
ref
<
Tree
[]
>
([])
// 部门树形结构化
const
deptTree
=
ref
<
Tree
[]
>
([])
// 部门树形结构化
const
deptList
=
ref
<
any
[]
>
([])
// 保存扁平化的部门列表数据
const
userList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 所有用户列表
const
userList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 所有用户列表
const
filteredUserList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 当前部门过滤后的用户列表
const
filteredUserList
=
ref
<
UserApi
.
UserVO
[]
>
([])
// 当前部门过滤后的用户列表
const
selectedUserIdList
:
any
=
ref
([])
// 选中的用户列表
const
selectedUserIdList
:
any
=
ref
([])
// 选中的用户列表
...
@@ -79,7 +80,9 @@ const open = async (id: number, selectedList?: any[]) => {
...
@@ -79,7 +80,9 @@ const open = async (id: number, selectedList?: any[]) => {
resetForm
()
resetForm
()
// 加载部门、用户列表
// 加载部门、用户列表
deptTree
.
value
=
handleTree
(
await
DeptApi
.
getSimpleDeptList
())
const
deptData
=
await
DeptApi
.
getSimpleDeptList
()
deptList
.
value
=
deptData
// 保存扁平结构的部门数据
deptTree
.
value
=
handleTree
(
deptData
)
// 转换成树形结构
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
// 初始状态下,过滤列表等于所有用户列表
// 初始状态下,过滤列表等于所有用户列表
...
@@ -88,16 +91,31 @@ const open = async (id: number, selectedList?: any[]) => {
...
@@ -88,16 +91,31 @@ const open = async (id: number, selectedList?: any[]) => {
dialogVisible
.
value
=
true
dialogVisible
.
value
=
true
}
}
/** 获取指定部门及其所有子部门的ID列表 */
const
getChildDeptIds
=
(
deptId
:
number
,
deptList
:
any
[]):
number
[]
=>
{
const
ids
=
[
deptId
]
const
children
=
deptList
.
filter
((
dept
)
=>
dept
.
parentId
===
deptId
)
children
.
forEach
((
child
)
=>
{
ids
.
push
(...
getChildDeptIds
(
child
.
id
,
deptList
))
})
return
ids
}
/** 获取部门过滤后的用户列表 */
/** 获取部门过滤后的用户列表 */
const
get
UserList
=
async
(
deptId
?:
number
)
=>
{
const
filter
UserList
=
async
(
deptId
?:
number
)
=>
{
formLoading
.
value
=
true
formLoading
.
value
=
true
try
{
try
{
// @ts-ignore
if
(
!
deptId
)
{
// TODO @芋艿:替换到 simple List 暂不支持 deptId 过滤
// 如果没有选择部门,显示所有用户
// TODO @Zqqq:这个,可以使用前端过滤么?通过 deptList 获取到 deptId 子节点,然后去 userList
filteredUserList
.
value
=
[...
userList
.
value
]
const
data
=
await
UserApi
.
getUserPage
({
pageSize
:
100
,
pageNo
:
1
,
deptId
})
return
// 更新过滤后的用户列表
}
filteredUserList
.
value
=
data
.
list
// 直接使用已保存的部门列表数据进行过滤
const
deptIds
=
getChildDeptIds
(
deptId
,
deptList
.
value
)
// 过滤出这些部门下的用户
filteredUserList
.
value
=
userList
.
value
.
filter
((
user
)
=>
deptIds
.
includes
(
user
.
deptId
))
}
finally
{
}
finally
{
formLoading
.
value
=
false
formLoading
.
value
=
false
}
}
...
@@ -121,6 +139,7 @@ const submitForm = async () => {
...
@@ -121,6 +139,7 @@ const submitForm = async () => {
/** 重置表单 */
/** 重置表单 */
const
resetForm
=
()
=>
{
const
resetForm
=
()
=>
{
deptTree
.
value
=
[]
deptTree
.
value
=
[]
deptList
.
value
=
[]
userList
.
value
=
[]
userList
.
value
=
[]
filteredUserList
.
value
=
[]
filteredUserList
.
value
=
[]
selectedUserIdList
.
value
=
[]
selectedUserIdList
.
value
=
[]
...
@@ -128,7 +147,7 @@ const resetForm = () => {
...
@@ -128,7 +147,7 @@ const resetForm = () => {
/** 处理部门被点击 */
/** 处理部门被点击 */
const
handleNodeClick
=
(
row
:
{
[
key
:
string
]:
any
})
=>
{
const
handleNodeClick
=
(
row
:
{
[
key
:
string
]:
any
})
=>
{
get
UserList
(
row
.
id
)
filter
UserList
(
row
.
id
)
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
...
...
src/components/bpmnProcessDesigner/package/penal/PropertiesPanel.vue
View file @
9685fbf8
<
template
>
<
template
>
<div
class=
"process-panel__container"
:style=
"
{ width: `${width}px` }">
<div
class=
"process-panel__container"
:style=
"
{ width: `${width}px` }">
<el-collapse
v-model=
"activeTab"
>
<el-collapse
v-model=
"activeTab"
v-if=
"isReady"
>
<el-collapse-item
name=
"base"
>
<el-collapse-item
name=
"base"
>
<!-- class="panel-tab__title" -->
<!-- class="panel-tab__title" -->
<template
#
title
>
<template
#
title
>
...
@@ -108,24 +108,16 @@ const elementBusinessObject = ref<any>({}) // 元素 businessObject 镜像,提
...
@@ -108,24 +108,16 @@ const elementBusinessObject = ref<any>({}) // 元素 businessObject 镜像,提
const
conditionFormVisible
=
ref
(
false
)
// 流转条件设置
const
conditionFormVisible
=
ref
(
false
)
// 流转条件设置
const
formVisible
=
ref
(
false
)
// 表单配置
const
formVisible
=
ref
(
false
)
// 表单配置
const
bpmnElement
=
ref
()
const
bpmnElement
=
ref
()
const
isReady
=
ref
(
false
)
provide
(
'prefix'
,
props
.
prefix
)
provide
(
'prefix'
,
props
.
prefix
)
provide
(
'width'
,
props
.
width
)
provide
(
'width'
,
props
.
width
)
const
bpmnInstances
=
()
=>
(
window
as
any
)?.
bpmnInstances
// 监听 props.bpmnModeler 然后 initModels
const
unwatchBpmn
=
watch
(
()
=>
props
.
bpmnModeler
,
()
=>
{
// 避免加载时 流程图 并未加载完成
if
(
!
props
.
bpmnModeler
)
{
console
.
log
(
'缺少props.bpmnModeler'
)
return
}
console
.
log
(
'props.bpmnModeler 有值了!!!'
)
// 初始化 bpmnInstances
const
w
=
window
as
any
const
initBpmnInstances
=
()
=>
{
w
.
bpmnInstances
=
{
if
(
!
props
.
bpmnModeler
)
return
false
try
{
const
instances
=
{
modeler
:
props
.
bpmnModeler
,
modeler
:
props
.
bpmnModeler
,
modeling
:
props
.
bpmnModeler
.
get
(
'modeling'
),
modeling
:
props
.
bpmnModeler
.
get
(
'modeling'
),
moddle
:
props
.
bpmnModeler
.
get
(
'moddle'
),
moddle
:
props
.
bpmnModeler
.
get
(
'moddle'
),
...
@@ -136,10 +128,46 @@ const unwatchBpmn = watch(
...
@@ -136,10 +128,46 @@ const unwatchBpmn = watch(
replace
:
props
.
bpmnModeler
.
get
(
'replace'
),
replace
:
props
.
bpmnModeler
.
get
(
'replace'
),
selection
:
props
.
bpmnModeler
.
get
(
'selection'
)
selection
:
props
.
bpmnModeler
.
get
(
'selection'
)
}
}
// 检查所有实例是否都存在
const
allInstancesExist
=
Object
.
values
(
instances
).
every
(
instance
=>
instance
)
if
(
allInstancesExist
)
{
const
w
=
window
as
any
w
.
bpmnInstances
=
instances
return
true
}
return
false
}
catch
(
error
)
{
console
.
error
(
'初始化 bpmnInstances 失败:'
,
error
)
return
false
}
}
const
bpmnInstances
=
()
=>
(
window
as
any
)?.
bpmnInstances
console
.
log
(
bpmnInstances
(),
'window.bpmnInstances'
)
// 监听 props.bpmnModeler 然后 initModels
getActiveElement
()
const
unwatchBpmn
=
watch
(
unwatchBpmn
()
()
=>
props
.
bpmnModeler
,
async
()
=>
{
// 避免加载时 流程图 并未加载完成
if
(
!
props
.
bpmnModeler
)
{
console
.
log
(
'缺少props.bpmnModeler'
)
return
}
try
{
// 等待 modeler 初始化完成
await
nextTick
()
if
(
initBpmnInstances
())
{
isReady
.
value
=
true
await
nextTick
()
getActiveElement
()
}
else
{
console
.
error
(
'modeler 实例未完全初始化'
)
}
}
catch
(
error
)
{
console
.
error
(
'初始化失败:'
,
error
)
}
},
},
{
{
immediate
:
true
immediate
:
true
...
@@ -147,6 +175,8 @@ const unwatchBpmn = watch(
...
@@ -147,6 +175,8 @@ const unwatchBpmn = watch(
)
)
const
getActiveElement
=
()
=>
{
const
getActiveElement
=
()
=>
{
if
(
!
isReady
.
value
||
!
props
.
bpmnModeler
)
return
// 初始第一个选中元素 bpmn:Process
// 初始第一个选中元素 bpmn:Process
initFormOnChanged
(
null
)
initFormOnChanged
(
null
)
props
.
bpmnModeler
.
on
(
'import.done'
,
(
e
)
=>
{
props
.
bpmnModeler
.
on
(
'import.done'
,
(
e
)
=>
{
...
@@ -164,8 +194,11 @@ const getActiveElement = () => {
...
@@ -164,8 +194,11 @@ const getActiveElement = () => {
}
}
})
})
}
}
// 初始化数据
// 初始化数据
const
initFormOnChanged
=
(
element
)
=>
{
const
initFormOnChanged
=
(
element
)
=>
{
if
(
!
isReady
.
value
||
!
bpmnInstances
())
return
let
activatedElement
=
element
let
activatedElement
=
element
if
(
!
activatedElement
)
{
if
(
!
activatedElement
)
{
activatedElement
=
activatedElement
=
...
@@ -173,32 +206,36 @@ const initFormOnChanged = (element) => {
...
@@ -173,32 +206,36 @@ const initFormOnChanged = (element) => {
bpmnInstances
().
elementRegistry
.
find
((
el
)
=>
el
.
type
===
'bpmn:Collaboration'
)
bpmnInstances
().
elementRegistry
.
find
((
el
)
=>
el
.
type
===
'bpmn:Collaboration'
)
}
}
if
(
!
activatedElement
)
return
if
(
!
activatedElement
)
return
console
.
log
(
`
----------
try
{
select element changed:
console
.
log
(
`
id:
${
activatedElement
.
id
}
----------
type:
${
activatedElement
.
businessObject
.
$type
}
select element changed:
----------
id:
${
activatedElement
.
id
}
`
)
type:
${
activatedElement
.
businessObject
.
$type
}
console
.
log
(
'businessObject: '
,
activatedElement
.
businessObject
)
----------
bpmnInstances
().
bpmnElement
=
activatedElement
`
)
bpmnElement
.
value
=
activatedElement
console
.
log
(
'businessObject: '
,
activatedElement
.
businessObject
)
elementId
.
value
=
activatedElement
.
id
bpmnInstances
().
bpmnElement
=
activatedElement
elementType
.
value
=
activatedElement
.
type
.
split
(
':'
)[
1
]
||
''
bpmnElement
.
value
=
activatedElement
elementBusinessObject
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
activatedElement
.
businessObject
))
elementId
.
value
=
activatedElement
.
id
conditionFormVisible
.
value
=
!!
(
elementType
.
value
=
activatedElement
.
type
.
split
(
':'
)[
1
]
||
''
elementType
.
value
===
'SequenceFlow'
&&
elementBusinessObject
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
activatedElement
.
businessObject
))
activatedElement
.
source
&&
conditionFormVisible
.
value
=
!!
(
activatedElement
.
source
.
type
.
indexOf
(
'StartEvent'
)
===
-
1
elementType
.
value
===
'SequenceFlow'
&&
)
activatedElement
.
source
&&
formVisible
.
value
=
elementType
.
value
===
'UserTask'
||
elementType
.
value
===
'StartEvent'
activatedElement
.
source
.
type
.
indexOf
(
'StartEvent'
)
===
-
1
)
formVisible
.
value
=
elementType
.
value
===
'UserTask'
||
elementType
.
value
===
'StartEvent'
}
catch
(
error
)
{
console
.
error
(
'初始化表单数据失败:'
,
error
)
}
}
}
onBeforeUnmount
(()
=>
{
onBeforeUnmount
(()
=>
{
const
w
=
window
as
any
const
w
=
window
as
any
w
.
bpmnInstances
=
null
w
.
bpmnInstances
=
null
console
.
log
(
props
,
'props1'
)
isReady
.
value
=
false
console
.
log
(
props
.
bpmnModeler
,
'props.bpmnModeler1'
)
})
})
watch
(
watch
(
...
...
src/router/modules/remaining.ts
View file @
9685fbf8
...
@@ -330,6 +330,18 @@ const remainingRouter: AppRouteRecordRaw[] = [
...
@@ -330,6 +330,18 @@ const remainingRouter: AppRouteRecordRaw[] = [
title
:
'查看 OA 请假'
,
title
:
'查看 OA 请假'
,
activeMenu
:
'/bpm/oa/leave'
activeMenu
:
'/bpm/oa/leave'
}
}
},
{
path
:
'manager/model/create-update'
,
component
:
()
=>
import
(
'@/views/bpm/model/CreateUpdate.vue'
),
name
:
'BpmModelCreateUpdate'
,
meta
:
{
noCache
:
true
,
hidden
:
true
,
canTo
:
true
,
title
:
'创建/修改流程'
,
activeMenu
:
'/bpm/manager/model'
}
}
}
]
]
},
},
...
...
src/views/bpm/model/CategoryDraggableModel.vue
View file @
9685fbf8
...
@@ -249,7 +249,7 @@ import { formatDate } from '@/utils/formatTime'
...
@@ -249,7 +249,7 @@ import { formatDate } from '@/utils/formatTime'
import
*
as
ModelApi
from
'@/api/bpm/model'
import
*
as
ModelApi
from
'@/api/bpm/model'
import
*
as
FormApi
from
'@/api/bpm/form'
import
*
as
FormApi
from
'@/api/bpm/form'
import
{
setConfAndFields2
}
from
'@/utils/formCreate'
import
{
setConfAndFields2
}
from
'@/utils/formCreate'
import
{
BpmModelFormType
,
BpmModelType
}
from
'@/utils/constants'
import
{
BpmModelFormType
}
from
'@/utils/constants'
import
{
checkPermi
}
from
'@/utils/permission'
import
{
checkPermi
}
from
'@/utils/permission'
import
{
useUserStoreWithOut
}
from
'@/store/modules/user'
import
{
useUserStoreWithOut
}
from
'@/store/modules/user'
import
{
useAppStore
}
from
'@/store/modules/app'
import
{
useAppStore
}
from
'@/store/modules/app'
...
@@ -339,21 +339,22 @@ const handleChangeState = async (row: any) => {
...
@@ -339,21 +339,22 @@ const handleChangeState = async (row: any) => {
/** 设计流程 */
/** 设计流程 */
const
handleDesign
=
(
row
:
any
)
=>
{
const
handleDesign
=
(
row
:
any
)
=>
{
if
(
row
.
type
==
BpmModelType
.
BPMN
)
{
// if (row.type == BpmModelType.BPMN) {
push
({
// push({
name
:
'BpmModelEditor'
,
// name: 'BpmModelEditor',
query
:
{
// query: {
modelId
:
row
.
id
// modelId: row.id
}
// }
})
// })
}
else
{
// } else {
push
({
// push({
name
:
'SimpleModelDesign'
,
// name: 'SimpleModelDesign',
query
:
{
// query: {
modelId
:
row
.
id
// modelId: row.id
}
// }
})
// })
}
// }
push
(
`/bpm/manager/model/create-update?id=
${
row
.
id
}
`
)
}
}
/** 发布流程 */
/** 发布流程 */
...
@@ -496,7 +497,11 @@ const handleDeleteCategory = async () => {
...
@@ -496,7 +497,11 @@ const handleDeleteCategory = async () => {
/** 添加流程模型弹窗 */
/** 添加流程模型弹窗 */
const
modelFormRef
=
ref
()
const
modelFormRef
=
ref
()
const
openModelForm
=
(
type
:
string
,
id
?:
number
)
=>
{
const
openModelForm
=
(
type
:
string
,
id
?:
number
)
=>
{
modelFormRef
.
value
.
open
(
type
,
id
)
if
(
type
===
'create'
)
{
push
(
'/bpm/manager/model/create-update'
)
}
else
{
push
(
`/bpm/manager/model/create-update?id=
${
id
}
`
)
}
}
}
watch
(()
=>
props
.
categoryInfo
.
modelList
,
updateModeList
,
{
immediate
:
true
})
watch
(()
=>
props
.
categoryInfo
.
modelList
,
updateModeList
,
{
immediate
:
true
})
...
...
src/views/bpm/model/CreateUpdate.vue
0 → 100644
View file @
9685fbf8
<
template
>
<!-- 头部导航栏 -->
<div
class=
"absolute top-0 left-0 right-0 h-50px bg-white border-bottom z-10 flex items-center px-20px"
>
<!-- 左侧标题,固定宽度 -->
<div
class=
"w-200px flex items-center overflow-hidden"
>
<Icon
icon=
"ep:arrow-left"
class=
"cursor-pointer flex-shrink-0"
@
click=
"router.back()"
/>
<span
class=
"ml-10px text-16px truncate"
:title=
"formData.name || '创建流程'"
>
{{
formData
.
name
||
'创建流程'
}}
</span>
</div>
<!-- 步骤条,固定在中间 -->
<div
class=
"flex-1 flex items-center justify-center h-full"
>
<div
class=
"w-400px flex items-center justify-between h-full"
>
<div
v-for=
"(step, index) in steps"
:key=
"index"
class=
"flex items-center cursor-pointer mx-15px relative h-full"
:class=
"[
currentStep === index
? 'text-[#3473ff] border-[#3473ff] border-b-2 border-b-solid'
: 'text-gray-500'
]"
@
click=
"handleStepClick(index)"
>
<div
class=
"w-28px h-28px rounded-full flex items-center justify-center mr-8px border-2 border-solid text-15px"
:class=
"[
currentStep === index
? 'bg-[#3473ff] text-white border-[#3473ff]'
: 'border-gray-300 bg-white text-gray-500'
]"
>
{{
index
+
1
}}
</div>
<span
class=
"text-16px font-bold whitespace-nowrap"
>
{{
step
.
title
}}
</span>
</div>
</div>
</div>
<!-- 右侧按钮,固定宽度 -->
<div
class=
"w-200px flex items-center justify-end gap-2"
>
<el-button
@
click=
"handleSave"
>
保 存
</el-button>
<el-button
type=
"primary"
@
click=
"handleDeploy"
>
发 布
</el-button>
</div>
</div>
<!-- 主体内容 -->
<ContentWrap
class=
"mt-50px"
>
<!-- 第一步:基本信息 -->
<div
v-show=
"currentStep === 0"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"120px"
class=
"mt-20px"
:class=
"
{ 'w-600px': currentStep === 0 }"
>
<el-form-item
label=
"流程标识"
prop=
"key"
class=
"mb-20px"
>
<el-input
v-model=
"formData.key"
:disabled=
"!!formData.id"
placeholder=
"请输入流标标识"
/>
<el-tooltip
v-if=
"!formData.id"
class=
"item"
content=
"新建后,流程标识不可修改!"
effect=
"light"
placement=
"top"
>
<Icon
icon=
"ep:question"
class=
"ml-5px"
/>
</el-tooltip>
<el-tooltip
v-else
class=
"item"
content=
"流程标识不可修改!"
effect=
"light"
placement=
"top"
>
<Icon
icon=
"ep:question"
class=
"ml-5px"
/>
</el-tooltip>
</el-form-item>
<el-form-item
label=
"流程名称"
prop=
"name"
class=
"mb-20px"
>
<el-input
v-model=
"formData.name"
:disabled=
"!!formData.id"
clearable
placeholder=
"请输入流程名称"
/>
</el-form-item>
<el-form-item
label=
"流程分类"
prop=
"category"
class=
"mb-20px"
>
<el-select
v-model=
"formData.category"
clearable
placeholder=
"请选择流程分类"
style=
"width: 100%"
>
<el-option
v-for=
"category in categoryList"
:key=
"category.code"
:label=
"category.name"
:value=
"category.code"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"流程图标"
prop=
"icon"
class=
"mb-20px"
>
<UploadImg
v-model=
"formData.icon"
:limit=
"1"
height=
"64px"
width=
"64px"
/>
</el-form-item>
<el-form-item
label=
"流程描述"
prop=
"description"
class=
"mb-20px"
>
<el-input
v-model=
"formData.description"
clearable
type=
"textarea"
/>
</el-form-item>
<el-form-item
label=
"流程类型"
prop=
"type"
class=
"mb-20px"
>
<el-radio-group
v-model=
"formData.type"
>
<el-radio
v-for=
"dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_TYPE)"
:key=
"dict.value"
:value=
"dict.value"
>
{{
dict
.
label
}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"是否可见"
prop=
"visible"
class=
"mb-20px"
>
<el-radio-group
v-model=
"formData.visible"
>
<el-radio
v-for=
"dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key=
"dict.value"
:value=
"dict.value"
>
{{
dict
.
label
}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
label=
"谁可以发起"
prop=
"startUserType"
class=
"mb-20px"
>
<el-select
v-model=
"formData.startUserType"
placeholder=
"请选择谁可以发起"
@
change=
"handleStartUserTypeChange"
>
<el-option
label=
"全员"
:value=
"0"
/>
<el-option
label=
"指定人员"
:value=
"1"
/>
<el-option
label=
"均不可提交"
:value=
"2"
/>
</el-select>
<div
v-if=
"formData.startUserType === 1"
class=
"mt-2 flex flex-wrap gap-2"
>
<div
v-for=
"user in selectedStartUsers"
:key=
"user.id"
class=
"bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-if=
"user.avatar"
:src=
"user.avatar"
/>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-else
>
{{
user
.
nickname
.
substring
(
0
,
1
)
}}
</el-avatar>
{{
user
.
nickname
}}
<Icon
icon=
"ep:close"
class=
"ml-2 cursor-pointer hover:text-red-500"
@
click=
"handleRemoveStartUser(user)"
/>
</div>
<el-button
type=
"primary"
link
@
click=
"openStartUserSelect"
>
<Icon
icon=
"ep:plus"
/>
选择人员
</el-button>
</div>
</el-form-item>
<el-form-item
label=
"流程管理员"
prop=
"managerUserType"
class=
"mb-20px"
>
<el-select
v-model=
"formData.managerUserType"
placeholder=
"请选择流程管理员"
@
change=
"handleManagerUserTypeChange"
>
<el-option
label=
"全员"
:value=
"0"
/>
<el-option
label=
"指定人员"
:value=
"1"
/>
<el-option
label=
"均不可提交"
:value=
"2"
/>
</el-select>
<div
v-if=
"formData.managerUserType === 1"
class=
"mt-2 flex flex-wrap gap-2"
>
<div
v-for=
"user in selectedManagerUsers"
:key=
"user.id"
class=
"bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-if=
"user.avatar"
:src=
"user.avatar"
/>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-else
>
{{
user
.
nickname
.
substring
(
0
,
1
)
}}
</el-avatar>
{{
user
.
nickname
}}
<Icon
icon=
"ep:close"
class=
"ml-2 cursor-pointer hover:text-red-500"
@
click=
"handleRemoveManagerUser(user)"
/>
</div>
<el-button
type=
"primary"
link
@
click=
"openManagerUserSelect"
>
<Icon
icon=
"ep:plus"
/>
选择人员
</el-button>
</div>
</el-form-item>
</el-form>
</div>
<div
v-if=
"currentStep === 1"
>
<!-- 第二步:表单设计 -->
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"120px"
class=
"mt-20px"
>
<el-form-item
label=
"表单类型"
prop=
"formType"
class=
"mb-20px"
>
<el-radio-group
v-model=
"formData.formType"
>
<el-radio
v-for=
"dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_FORM_TYPE)"
:key=
"dict.value"
:value=
"dict.value"
>
{{
dict
.
label
}}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"formData.formType === 10"
label=
"流程表单"
prop=
"formId"
>
<el-select
v-model=
"formData.formId"
clearable
style=
"width: 100%"
>
<el-option
v-for=
"form in formList"
:key=
"form.id"
:label=
"form.name"
:value=
"form.id"
/>
</el-select>
</el-form-item>
<el-form-item
v-if=
"formData.formType === 20"
label=
"表单提交路由"
prop=
"formCustomCreatePath"
>
<el-input
v-model=
"formData.formCustomCreatePath"
placeholder=
"请输入表单提交路由"
style=
"width: 330px"
/>
<el-tooltip
class=
"item"
content=
"自定义表单的提交路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/create.vue"
effect=
"light"
placement=
"top"
>
<Icon
icon=
"ep:question"
class=
"ml-5px"
/>
</el-tooltip>
</el-form-item>
<el-form-item
v-if=
"formData.formType === 20"
label=
"表单查看地址"
prop=
"formCustomViewPath"
>
<el-input
v-model=
"formData.formCustomViewPath"
placeholder=
"请输入表单查看的组件地址"
style=
"width: 330px"
/>
<el-tooltip
class=
"item"
content=
"自定义表单的查看组件地址,使用 Vue 的组件地址,例如说:bpm/oa/leave/detail.vue"
effect=
"light"
placement=
"top"
>
<Icon
icon=
"ep:question"
class=
"ml-5px"
/>
</el-tooltip>
</el-form-item>
</el-form>
</div>
<!-- 第三步:流程设计 -->
<div
v-show=
"currentStep === 2"
>
<!-- BPMN设计器 -->
<template
v-if=
"formData.type === BpmModelType.BPMN"
>
<BpmModelEditor
v-if=
"showDesigner"
:model-id=
"formData.id"
:model-key=
"formData.key"
:model-name=
"formData.name"
@
success=
"handleDesignSuccess"
/>
</
template
>
<!-- Simple设计器 -->
<
template
v-else
>
<SimpleModelDesign
v-if=
"showDesigner"
:model-id=
"formData.id"
:model-key=
"formData.key"
:model-name=
"formData.name"
@
success=
"handleDesignSuccess"
/>
</
template
>
</div>
</ContentWrap>
<!-- 用户选择弹窗 -->
<UserSelectForm
ref=
"userSelectFormRef"
@
confirm=
"handleUserSelectConfirm"
/>
</template>
<
script
lang=
"ts"
setup
>
import
*
as
ModelApi
from
'@/api/bpm/model'
import
*
as
FormApi
from
'@/api/bpm/form'
import
{
CategoryApi
}
from
'@/api/bpm/category'
import
{
DICT_TYPE
,
getBoolDictOptions
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
BpmModelFormType
,
BpmModelType
}
from
'@/utils/constants'
import
*
as
UserApi
from
'@/api/system/user'
import
{
useUserStoreWithOut
}
from
'@/store/modules/user'
import
{
UserVO
}
from
'@/api/system/user'
import
BpmModelEditor
from
'./editor/index.vue'
import
SimpleModelDesign
from
'../simple/SimpleModelDesign.vue'
const
message
=
useMessage
()
// 消息弹窗
const
router
=
useRouter
()
const
route
=
useRoute
()
const
userStore
=
useUserStoreWithOut
()
// 步骤控制
const
currentStep
=
ref
(
0
)
// 表单数据
const
formRef
=
ref
()
const
formData
:
any
=
ref
({
id
:
undefined
,
name
:
''
,
key
:
''
,
category
:
undefined
,
icon
:
undefined
,
description
:
''
,
type
:
BpmModelType
.
BPMN
,
formType
:
BpmModelFormType
.
NORMAL
,
formId
:
''
,
formCustomCreatePath
:
''
,
formCustomViewPath
:
''
,
visible
:
true
,
startUserType
:
undefined
,
managerUserType
:
undefined
,
startUserIds
:
[],
managerUserIds
:
[]
})
// 表单校验规则
const
formRules
=
{
name
:
[{
required
:
true
,
message
:
'流程名称不能为空'
,
trigger
:
'blur'
}],
key
:
[{
required
:
true
,
message
:
'流程标识不能为空'
,
trigger
:
'blur'
}],
category
:
[{
required
:
true
,
message
:
'流程分类不能为空'
,
trigger
:
'blur'
}],
icon
:
[{
required
:
true
,
message
:
'流程图标不能为空'
,
trigger
:
'blur'
}],
type
:
[{
required
:
true
,
message
:
'是否可见不能为空'
,
trigger
:
'blur'
}],
formType
:
[{
required
:
true
,
message
:
'是否可见不能为空'
,
trigger
:
'blur'
}],
formId
:
[{
required
:
true
,
message
:
'流程表单不能为空'
,
trigger
:
'blur'
}],
formCustomCreatePath
:
[{
required
:
true
,
message
:
'表单提交路由不能为空'
,
trigger
:
'blur'
}],
formCustomViewPath
:
[{
required
:
true
,
message
:
'表单查看地址不能为空'
,
trigger
:
'blur'
}],
visible
:
[{
required
:
true
,
message
:
'是否可见不能为空'
,
trigger
:
'blur'
}],
managerUserIds
:
[{
required
:
true
,
message
:
'流程管理员不能为空'
,
trigger
:
'blur'
}]
}
// 流程设计器相关
const
xmlString
=
ref
(
undefined
)
// 数据列表
const
formList
:
any
=
ref
([])
const
categoryList
:
any
=
ref
([])
const
userList
=
ref
<
UserVO
[]
>
([])
const
selectedStartUsers
=
ref
<
UserVO
[]
>
([])
const
selectedManagerUsers
=
ref
<
UserVO
[]
>
([])
// 用户选择相关
const
userSelectFormRef
=
ref
()
const
currentSelectType
=
ref
<
'start'
|
'manager'
>
(
'start'
)
// 打开发起人选择
const
openStartUserSelect
=
()
=>
{
currentSelectType
.
value
=
'start'
userSelectFormRef
.
value
.
open
(
0
,
selectedStartUsers
.
value
)
}
// 打开管理员选择
const
openManagerUserSelect
=
()
=>
{
currentSelectType
.
value
=
'manager'
userSelectFormRef
.
value
.
open
(
0
,
selectedManagerUsers
.
value
)
}
// 处理用户选择确认
const
handleUserSelectConfirm
=
(
_
,
users
:
UserVO
[])
=>
{
if
(
currentSelectType
.
value
===
'start'
)
{
selectedStartUsers
.
value
=
users
formData
.
value
.
startUserIds
=
users
.
map
((
u
)
=>
u
.
id
)
}
else
{
selectedManagerUsers
.
value
=
users
formData
.
value
.
managerUserIds
=
users
.
map
((
u
)
=>
u
.
id
)
}
}
// 处理发起人类型变化
const
handleStartUserTypeChange
=
(
value
:
number
)
=>
{
if
(
value
!==
1
)
{
selectedStartUsers
.
value
=
[]
formData
.
value
.
startUserIds
=
[]
}
}
// 处理管理员类型变化
const
handleManagerUserTypeChange
=
(
value
:
number
)
=>
{
if
(
value
!==
1
)
{
selectedManagerUsers
.
value
=
[]
formData
.
value
.
managerUserIds
=
[]
}
}
// 移除发起人
const
handleRemoveStartUser
=
(
user
:
UserVO
)
=>
{
selectedStartUsers
.
value
=
selectedStartUsers
.
value
.
filter
((
u
)
=>
u
.
id
!==
user
.
id
)
formData
.
value
.
startUserIds
=
formData
.
value
.
startUserIds
.
filter
((
id
)
=>
id
!==
user
.
id
)
}
// 移除管理员
const
handleRemoveManagerUser
=
(
user
:
UserVO
)
=>
{
selectedManagerUsers
.
value
=
selectedManagerUsers
.
value
.
filter
((
u
)
=>
u
.
id
!==
user
.
id
)
formData
.
value
.
managerUserIds
=
formData
.
value
.
managerUserIds
.
filter
((
id
)
=>
id
!==
user
.
id
)
}
// 保存操作
const
handleSave
=
async
()
=>
{
try
{
if
(
formData
.
value
.
id
)
{
await
ModelApi
.
updateModel
(
formData
.
value
)
message
.
success
(
'修改成功'
)
}
else
{
const
result
=
await
ModelApi
.
createModel
(
formData
.
value
)
formData
.
value
.
id
=
result
.
id
// 保存id用于设计器
message
.
success
(
'新增成功'
)
}
// 不再跳转,继续停留在当前页面
}
catch
(
error
)
{
console
.
error
(
'保存失败:'
,
error
)
}
}
// 发布操作
const
handleDeploy
=
async
()
=>
{
try
{
await
message
.
confirm
(
'是否确认发布该流程?'
)
// 发布时才进行全部校验
await
validateAllSteps
()
await
handleSave
()
await
ModelApi
.
deployModel
(
formData
.
value
.
id
)
message
.
success
(
'发布成功'
)
router
.
push
({
path
:
'/bpm/manager/model'
})
}
catch
(
error
)
{
if
(
error
instanceof
Error
)
{
// 校验失败时,跳转到对应步骤
const
failedStep
=
steps
.
findIndex
((
step
)
=>
{
try
{
step
.
validator
&&
step
.
validator
()
return
false
}
catch
{
return
true
}
})
if
(
failedStep
!==
-
1
)
{
currentStep
.
value
=
failedStep
message
.
warning
(
'请完善必填信息'
)
}
}
}
}
// 初始化数据
const
initData
=
async
()
=>
{
const
modelId
=
route
.
query
.
id
as
unknown
as
string
if
(
modelId
)
{
// 修改场景
formData
.
value
=
await
ModelApi
.
getModel
(
modelId
)
// 加载数据时,根据已有的用户ID列表初始化已选用户
if
(
formData
.
value
.
startUserIds
?.
length
)
{
formData
.
value
.
startUserType
=
1
selectedStartUsers
.
value
=
userList
.
value
.
filter
((
user
)
=>
formData
.
value
.
startUserIds
.
includes
(
user
.
id
)
)
}
if
(
formData
.
value
.
managerUserIds
?.
length
)
{
formData
.
value
.
managerUserType
=
1
selectedManagerUsers
.
value
=
userList
.
value
.
filter
((
user
)
=>
formData
.
value
.
managerUserIds
.
includes
(
user
.
id
)
)
}
}
else
{
// 新增场景
formData
.
value
.
managerUserIds
.
push
(
userStore
.
getUser
.
id
)
}
// 获取表单列表
formList
.
value
=
await
FormApi
.
getFormSimpleList
()
// 获取分类列表
categoryList
.
value
=
await
CategoryApi
.
getCategorySimpleList
()
// 获取用户列表
userList
.
value
=
await
UserApi
.
getSimpleUserList
()
}
onMounted
(
async
()
=>
{
await
initData
()
})
// 第一步校验
const
validateStep1
=
async
()
=>
{
await
formRef
.
value
?.
validate
([
'name'
,
'key'
,
'category'
,
'icon'
,
'type'
,
'visible'
])
}
// 第二步校验
const
validateStep2
=
async
()
=>
{
await
formRef
.
value
?.
validate
([
'formType'
,
'formId'
,
'formCustomCreatePath'
,
'formCustomViewPath'
])
}
// 第三步校验
const
validateStep3
=
async
()
=>
{
if
(
!
xmlString
.
value
)
{
throw
new
Error
(
'请设计流程'
)
}
}
const
validateAllSteps
=
async
()
=>
{
for
(
const
step
of
steps
)
{
if
(
step
.
validator
)
{
await
step
.
validator
()
}
}
}
const
steps
=
[
{
title
:
'基本信息'
,
validator
:
validateStep1
},
{
title
:
'表单设计'
,
validator
:
validateStep2
},
{
title
:
'流程设计'
,
validator
:
validateStep3
}
]
// 处理设计器保存成功
const
handleDesignSuccess
=
(
bpmnXml
?:
string
)
=>
{
if
(
bpmnXml
)
{
// 新建时,保存设计器生成的XML
formData
.
value
.
bpmnXml
=
bpmnXml
}
message
.
success
(
'保存成功'
)
}
// 步骤切换处理
const
handleStepClick
=
async
(
index
:
number
)
=>
{
// 如果是切换到第三步(流程设计),需要校验key和name
if
(
index
===
2
)
{
if
(
!
formData
.
value
.
key
||
!
formData
.
value
.
name
)
{
message
.
warning
(
'请先填写流程标识和流程名称'
)
return
}
}
currentStep
.
value
=
index
}
// 添加一个计算属性来判断是否显示设计器
const
showDesigner
=
computed
(()
=>
{
return
(
currentStep
.
value
===
2
&&
Boolean
(
formData
.
value
.
id
||
(
formData
.
value
.
key
&&
formData
.
value
.
name
))
)
})
// 监听步骤变化,确保数据准备完成
watch
(
()
=>
currentStep
.
value
,
async
(
newStep
)
=>
{
if
(
newStep
===
2
)
{
await
nextTick
()
}
},
{
immediate
:
false
}
)
// 在组件卸载时清理
onBeforeUnmount
(()
=>
{
const
w
=
window
as
any
if
(
w
.
bpmnInstances
)
{
w
.
bpmnInstances
=
null
}
})
</
script
>
<
style
lang=
"scss"
scoped
>
.process-panel
{
position
:
absolute
;
top
:
0
;
right
:
0
;
}
.bg-gray-100
{
background-color
:
#f5f7fa
;
transition
:
all
0.3s
;
&:hover
{
background-color
:
#e6e8eb
;
}
.ep-close
{
font-size
:
14px
;
color
:
#909399
;
transition
:
color
0.3s
;
&:hover
{
color
:
#f56c6c
;
}
}
}
.border-bottom
{
border-bottom
:
1px
solid
#dcdfe6
;
}
.text-primary
{
color
:
#3473ff
;
}
.bg-primary
{
background-color
:
#3473ff
;
}
.border-primary
{
border-color
:
#3473ff
;
}
.text-16px
{
font-size
:
16px
;
}
.h-2px
{
height
:
2px
;
}
.mx-15px
{
margin-left
:
15px
;
margin-right
:
15px
;
}
</
style
>
src/views/bpm/model/ModelForm.vue
View file @
9685fbf8
...
@@ -123,29 +123,69 @@
...
@@ -123,29 +123,69 @@
</el-radio>
</el-radio>
</el-radio-group>
</el-radio-group>
</el-form-item>
</el-form-item>
<el-form-item
label=
"谁可以发起"
prop=
"startUser
Ids
"
>
<el-form-item
label=
"谁可以发起"
prop=
"startUser
Type
"
>
<el-select
<el-select
v-model=
"formData.startUser
Ids
"
v-model=
"formData.startUser
Type
"
multiple
placeholder=
"请选择谁可以发起"
placeholder=
"请选择可发起人,默认(不选择)则所有人都可以发起
"
@
change=
"handleStartUserTypeChange
"
>
>
<el-option
<el-option
label=
"全员"
:value=
"0"
/>
v-for=
"user in userList"
<el-option
label=
"指定人员"
:value=
"1"
/>
:key=
"user.id"
<el-option
label=
"均不可提交"
:value=
"2"
/>
:label=
"user.nickname"
:value=
"user.id"
/>
</el-select>
</el-select>
</el-form-item>
<div
v-if=
"formData.startUserType === 1"
class=
"mt-2 flex flex-wrap gap-2"
>
<el-form-item
label=
"流程管理员"
prop=
"managerUserIds"
>
<div
<el-select
v-model=
"formData.managerUserIds"
multiple
placeholder=
"请选择流程管理员"
>
v-for=
"user in selectedStartUsers"
<el-option
v-for=
"user in userList"
:key=
"user.id"
:key=
"user.id"
:label=
"user.nickname"
class=
"bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
:value=
"user.id"
>
/>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-if=
"user.avatar"
:src=
"user.avatar"
/>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-else
>
{{
user
.
nickname
.
substring
(
0
,
1
)
}}
</el-avatar>
{{
user
.
nickname
}}
<Icon
icon=
"ep:close"
class=
"ml-2 cursor-pointer hover:text-red-500"
@
click=
"handleRemoveStartUser(user)"
/>
</div>
<el-button
type=
"primary"
link
@
click=
"openStartUserSelect"
>
<Icon
icon=
"ep:plus"
/>
选择人员
</el-button>
</div>
</el-form-item>
<el-form-item
label=
"流程管理员"
prop=
"managerUserType"
>
<el-select
v-model=
"formData.managerUserType"
placeholder=
"请选择流程管理员"
@
change=
"handleManagerUserTypeChange"
>
<el-option
label=
"全员"
:value=
"0"
/>
<el-option
label=
"指定人员"
:value=
"1"
/>
<el-option
label=
"均不可提交"
:value=
"2"
/>
</el-select>
</el-select>
<div
v-if=
"formData.managerUserType === 1"
class=
"mt-2 flex flex-wrap gap-2"
>
<div
v-for=
"user in selectedManagerUsers"
:key=
"user.id"
class=
"bg-gray-100 h-35px rounded-3xl flex items-center pr-8px dark:color-gray-600 position-relative"
>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-if=
"user.avatar"
:src=
"user.avatar"
/>
<el-avatar
class=
"!m-5px"
:size=
"28"
v-else
>
{{
user
.
nickname
.
substring
(
0
,
1
)
}}
</el-avatar>
{{
user
.
nickname
}}
<Icon
icon=
"ep:close"
class=
"ml-2 cursor-pointer hover:text-red-500"
@
click=
"handleRemoveManagerUser(user)"
/>
</div>
<el-button
type=
"primary"
link
@
click=
"openManagerUserSelect"
>
<Icon
icon=
"ep:plus"
/>
选择人员
</el-button>
</div>
</el-form-item>
</el-form-item>
</el-form>
</el-form>
<template
#
footer
>
<template
#
footer
>
...
@@ -153,6 +193,7 @@
...
@@ -153,6 +193,7 @@
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
<el-button
@
click=
"dialogVisible = false"
>
取 消
</el-button>
</
template
>
</
template
>
</Dialog>
</Dialog>
<UserSelectForm
ref=
"userSelectFormRef"
@
confirm=
"handleUserSelectConfirm"
/>
</template>
</template>
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
propTypes
}
from
'@/utils/propTypes'
import
{
propTypes
}
from
'@/utils/propTypes'
...
@@ -178,7 +219,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
...
@@ -178,7 +219,7 @@ const dialogVisible = ref(false) // 弹窗的是否展示
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
dialogTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
const
formData
:
any
=
ref
({
id
:
undefined
,
id
:
undefined
,
name
:
''
,
name
:
''
,
key
:
''
,
key
:
''
,
...
@@ -191,6 +232,8 @@ const formData = ref({
...
@@ -191,6 +232,8 @@ const formData = ref({
formCustomCreatePath
:
''
,
formCustomCreatePath
:
''
,
formCustomViewPath
:
''
,
formCustomViewPath
:
''
,
visible
:
true
,
visible
:
true
,
startUserType
:
undefined
,
managerUserType
:
undefined
,
startUserIds
:
[],
startUserIds
:
[],
managerUserIds
:
[]
managerUserIds
:
[]
})
})
...
@@ -211,6 +254,10 @@ const formRef = ref() // 表单 Ref
...
@@ -211,6 +254,10 @@ const formRef = ref() // 表单 Ref
const
formList
=
ref
([])
// 流程表单的下拉框的数据
const
formList
=
ref
([])
// 流程表单的下拉框的数据
const
categoryList
=
ref
([])
// 流程分类列表
const
categoryList
=
ref
([])
// 流程分类列表
const
userList
=
ref
<
UserVO
[]
>
([])
// 用户列表
const
userList
=
ref
<
UserVO
[]
>
([])
// 用户列表
const
selectedStartUsers
=
ref
<
UserVO
[]
>
([])
// 已选择的发起人列表
const
selectedManagerUsers
=
ref
<
UserVO
[]
>
([])
// 已选择的管理员列表
const
userSelectFormRef
=
ref
()
// 用户选择弹窗ref
const
currentSelectType
=
ref
<
'start'
|
'manager'
>
(
'start'
)
// 当前选择的是发起人还是管理员
/** 打开弹窗 */
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
string
)
=>
{
const
open
=
async
(
type
:
string
,
id
?:
string
)
=>
{
...
@@ -226,6 +273,19 @@ const open = async (type: string, id?: string) => {
...
@@ -226,6 +273,19 @@ const open = async (type: string, id?: string) => {
}
finally
{
}
finally
{
formLoading
.
value
=
false
formLoading
.
value
=
false
}
}
// 加载数据时,根据已有的用户ID列表初始化已选用户
if
(
formData
.
value
.
startUserIds
?.
length
)
{
formData
.
value
.
startUserType
=
1
selectedStartUsers
.
value
=
userList
.
value
.
filter
((
user
)
=>
formData
.
value
.
startUserIds
.
includes
(
user
.
id
)
)
}
if
(
formData
.
value
.
managerUserIds
?.
length
)
{
formData
.
value
.
managerUserType
=
1
selectedManagerUsers
.
value
=
userList
.
value
.
filter
((
user
)
=>
formData
.
value
.
managerUserIds
.
includes
(
user
.
id
)
)
}
}
else
{
}
else
{
formData
.
value
.
managerUserIds
.
push
(
userStore
.
getUser
.
id
)
formData
.
value
.
managerUserIds
.
push
(
userStore
.
getUser
.
id
)
}
}
...
@@ -293,9 +353,85 @@ const resetForm = () => {
...
@@ -293,9 +353,85 @@ const resetForm = () => {
formCustomCreatePath
:
''
,
formCustomCreatePath
:
''
,
formCustomViewPath
:
''
,
formCustomViewPath
:
''
,
visible
:
true
,
visible
:
true
,
startUserType
:
undefined
,
managerUserType
:
undefined
,
startUserIds
:
[],
startUserIds
:
[],
managerUserIds
:
[]
managerUserIds
:
[]
}
}
formRef
.
value
?.
resetFields
()
formRef
.
value
?.
resetFields
()
selectedStartUsers
.
value
=
[]
selectedManagerUsers
.
value
=
[]
}
// 处理发起人类型变化
const
handleStartUserTypeChange
=
(
value
:
number
)
=>
{
if
(
value
!==
1
)
{
selectedStartUsers
.
value
=
[]
formData
.
value
.
startUserIds
=
[]
}
}
// 处理管理员类型变化
const
handleManagerUserTypeChange
=
(
value
:
number
)
=>
{
if
(
value
!==
1
)
{
selectedManagerUsers
.
value
=
[]
formData
.
value
.
managerUserIds
=
[]
}
}
// 打开发起人选择
const
openStartUserSelect
=
()
=>
{
currentSelectType
.
value
=
'start'
userSelectFormRef
.
value
.
open
(
0
,
selectedStartUsers
.
value
)
}
// 打开管理员选择
const
openManagerUserSelect
=
()
=>
{
currentSelectType
.
value
=
'manager'
userSelectFormRef
.
value
.
open
(
0
,
selectedManagerUsers
.
value
)
}
// 处理用户选择确认
const
handleUserSelectConfirm
=
(
_
,
users
:
UserVO
[])
=>
{
if
(
currentSelectType
.
value
===
'start'
)
{
selectedStartUsers
.
value
=
users
formData
.
value
.
startUserIds
=
users
.
map
((
u
)
=>
u
.
id
)
}
else
{
selectedManagerUsers
.
value
=
users
formData
.
value
.
managerUserIds
=
users
.
map
((
u
)
=>
u
.
id
)
}
}
// 移除发起人
const
handleRemoveStartUser
=
(
user
:
UserVO
)
=>
{
selectedStartUsers
.
value
=
selectedStartUsers
.
value
.
filter
((
u
)
=>
u
.
id
!==
user
.
id
)
formData
.
value
.
startUserIds
=
formData
.
value
.
startUserIds
.
filter
((
id
)
=>
id
!==
user
.
id
)
}
// 移除管理员
const
handleRemoveManagerUser
=
(
user
:
UserVO
)
=>
{
selectedManagerUsers
.
value
=
selectedManagerUsers
.
value
.
filter
((
u
)
=>
u
.
id
!==
user
.
id
)
formData
.
value
.
managerUserIds
=
formData
.
value
.
managerUserIds
.
filter
((
id
)
=>
id
!==
user
.
id
)
}
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
.bg-gray-100
{
background-color
:
#f5f7fa
;
transition
:
all
0.3s
;
&:hover
{
background-color
:
#e6e8eb
;
}
.ep-close
{
font-size
:
14px
;
color
:
#909399
;
transition
:
color
0.3s
;
&:hover
{
color
:
#f56c6c
;
}
}
}
</
style
>
src/views/bpm/model/editor/index.vue
View file @
9685fbf8
...
@@ -3,7 +3,6 @@
...
@@ -3,7 +3,6 @@
<!-- 流程设计器,负责绘制流程等 -->
<!-- 流程设计器,负责绘制流程等 -->
<MyProcessDesigner
<MyProcessDesigner
key=
"designer"
key=
"designer"
v-if=
"xmlString !== undefined"
v-model=
"xmlString"
v-model=
"xmlString"
:value=
"xmlString"
:value=
"xmlString"
v-bind=
"controlForm"
v-bind=
"controlForm"
...
@@ -11,12 +10,14 @@
...
@@ -11,12 +10,14 @@
ref=
"processDesigner"
ref=
"processDesigner"
@
init-finished=
"initModeler"
@
init-finished=
"initModeler"
:additionalModel=
"controlForm.additionalModel"
:additionalModel=
"controlForm.additionalModel"
:model=
"model"
@
save=
"save"
@
save=
"save"
/>
/>
<!-- 流程属性器,负责编辑每个流程节点的属性 -->
<!-- 流程属性器,负责编辑每个流程节点的属性 -->
<MyProcessPenal
<MyProcessPenal
v-if=
"isModelerReady && modeler"
key=
"penal"
key=
"penal"
:bpmnModeler=
"modeler
as any
"
:bpmnModeler=
"modeler"
:prefix=
"controlForm.prefix"
:prefix=
"controlForm.prefix"
class=
"process-panel"
class=
"process-panel"
:model=
"model"
:model=
"model"
...
@@ -34,12 +35,19 @@ import * as ModelApi from '@/api/bpm/model'
...
@@ -34,12 +35,19 @@ import * as ModelApi from '@/api/bpm/model'
defineOptions
({
name
:
'BpmModelEditor'
})
defineOptions
({
name
:
'BpmModelEditor'
})
const
router
=
useRouter
()
// 路由
const
props
=
defineProps
<
{
const
{
query
}
=
useRoute
()
// 路由的查询
modelId
?:
string
modelKey
?:
string
modelName
?:
string
}
>
()
const
emit
=
defineEmits
([
'success'
])
const
message
=
useMessage
()
// 国际化
const
message
=
useMessage
()
// 国际化
const
xmlString
=
ref
(
undefined
)
// BPMN XML
const
xmlString
=
ref
<
string
>
(
''
)
// BPMN XML
const
modeler
=
ref
(
null
)
// BPMN Modeler
const
modeler
=
shallowRef
()
// BPMN Modeler
const
processDesigner
=
ref
()
const
isModelerReady
=
ref
(
false
)
const
controlForm
=
ref
({
const
controlForm
=
ref
({
simulation
:
true
,
simulation
:
true
,
labelEditing
:
false
,
labelEditing
:
false
,
...
@@ -50,60 +58,142 @@ const controlForm = ref({
...
@@ -50,60 +58,142 @@ const controlForm = ref({
})
})
const
model
=
ref
<
ModelApi
.
ModelVO
>
()
// 流程模型的信息
const
model
=
ref
<
ModelApi
.
ModelVO
>
()
// 流程模型的信息
// 初始化 bpmnInstances
const
initBpmnInstances
=
()
=>
{
if
(
!
modeler
.
value
)
return
false
try
{
const
instances
=
{
modeler
:
modeler
.
value
,
modeling
:
modeler
.
value
.
get
(
'modeling'
),
moddle
:
modeler
.
value
.
get
(
'moddle'
),
eventBus
:
modeler
.
value
.
get
(
'eventBus'
),
bpmnFactory
:
modeler
.
value
.
get
(
'bpmnFactory'
),
elementFactory
:
modeler
.
value
.
get
(
'elementFactory'
),
elementRegistry
:
modeler
.
value
.
get
(
'elementRegistry'
),
replace
:
modeler
.
value
.
get
(
'replace'
),
selection
:
modeler
.
value
.
get
(
'selection'
)
}
// 检查所有实例是否都存在
return
Object
.
values
(
instances
).
every
(
instance
=>
instance
)
}
catch
(
error
)
{
console
.
error
(
'初始化 bpmnInstances 失败:'
,
error
)
return
false
}
}
/** 初始化 modeler */
/** 初始化 modeler */
const
initModeler
=
(
item
)
=>
{
const
initModeler
=
async
(
item
)
=>
{
setTimeout
(()
=>
{
try
{
modeler
.
value
=
item
modeler
.
value
=
item
},
10
)
// 等待 modeler 初始化完成
await
nextTick
()
// 确保 modeler 的所有实例都已经准备好
if
(
initBpmnInstances
())
{
isModelerReady
.
value
=
true
if
(
!
props
.
modelId
&&
props
.
modelKey
&&
props
.
modelName
)
{
await
updateModelData
(
props
.
modelKey
,
props
.
modelName
)
}
}
else
{
console
.
error
(
'modeler 实例未完全初始化'
)
}
}
catch
(
error
)
{
console
.
error
(
'初始化 modeler 失败:'
,
error
)
}
}
/** 获取默认的BPMN XML */
const
getDefaultBpmnXml
=
(
key
:
string
,
name
:
string
)
=>
{
return
`<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.activiti.org/processdef">
<process id="
${
key
}
" name="
${
name
}
" isExecutable="true" />
<bpmndi:BPMNDiagram id="BPMNDiagram">
<bpmndi:BPMNPlane id="
${
key
}
_di" bpmnElement="
${
key
}
" />
</bpmndi:BPMNDiagram>
</definitions>`
}
}
/** 添加/修改模型 */
/** 添加/修改模型 */
const
save
=
async
(
bpmnXml
:
string
)
=>
{
const
save
=
async
(
bpmnXml
:
string
)
=>
{
const
data
=
{
try
{
...
model
.
value
,
if
(
props
.
modelId
)
{
bpmnXml
:
bpmnXml
// bpmnXml 只是初始化流程图,后续修改无法通过它获得
// 编辑模式
}
as
unknown
as
ModelApi
.
ModelVO
const
data
=
{
// 提交
...
model
.
value
,
if
(
data
.
id
)
{
bpmnXml
:
bpmnXml
await
ModelApi
.
updateModelBpmn
(
data
)
}
as
unknown
as
ModelApi
.
ModelVO
message
.
success
(
'修改成功'
)
await
ModelApi
.
updateModelBpmn
(
data
)
}
else
{
emit
(
'success'
)
await
ModelApi
.
updateModelBpmn
(
data
)
}
else
{
message
.
success
(
'新增成功'
)
// 新建模式,直接返回XML
emit
(
'success'
,
bpmnXml
)
}
}
catch
(
error
)
{
console
.
error
(
'保存失败:'
,
error
)
message
.
error
(
'保存失败'
)
}
}
// 跳转回去
close
()
}
/** 关闭按钮 */
const
close
=
()
=>
{
router
.
push
({
path
:
'/bpm/manager/model'
})
}
}
/** 初始化 */
/** 初始化 */
onMounted
(
async
()
=>
{
onMounted
(
async
()
=>
{
const
modelId
=
query
.
modelId
as
unknown
as
number
try
{
if
(
!
modelId
)
{
if
(
props
.
modelId
)
{
message
.
error
(
'缺少模型 modelId 编号'
)
// 编辑模式
return
// 查询模型
const
data
=
await
ModelApi
.
getModel
(
props
.
modelId
)
model
.
value
=
{
...
data
,
bpmnXml
:
undefined
// 清空 bpmnXml 属性
}
xmlString
.
value
=
data
.
bpmnXml
||
getDefaultBpmnXml
(
data
.
key
,
data
.
name
)
}
else
if
(
props
.
modelKey
&&
props
.
modelName
)
{
// 新建模式
xmlString
.
value
=
getDefaultBpmnXml
(
props
.
modelKey
,
props
.
modelName
)
model
.
value
=
{
key
:
props
.
modelKey
,
name
:
props
.
modelName
}
as
ModelApi
.
ModelVO
}
}
catch
(
error
)
{
console
.
error
(
'初始化失败:'
,
error
)
message
.
error
(
'初始化失败'
)
}
}
// 查询模型
})
const
data
=
await
ModelApi
.
getModel
(
modelId
)
if
(
!
data
.
bpmnXml
)
{
// 更新模型数据
// 首次创建的 Model 模型,它是没有 bpmnXml,此时需要给它一个默认的
const
updateModelData
=
async
(
key
?:
string
,
name
?:
string
)
=>
{
data
.
bpmnXml
=
` <?xml version="1.0" encoding="UTF-8"?>
if
(
key
&&
name
)
{
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.activiti.org/processdef">
xmlString
.
value
=
getDefaultBpmnXml
(
key
,
name
)
<process id="
${
data
.
key
}
" name="
${
data
.
name
}
" isExecutable="true" />
model
.
value
=
{
<bpmndi:BPMNDiagram id="BPMNDiagram">
...
model
.
value
,
<bpmndi:BPMNPlane id="
${
data
.
key
}
_di" bpmnElement="
${
data
.
key
}
" />
key
:
key
,
</bpmndi:BPMNDiagram>
name
:
name
</definitions>`
}
as
ModelApi
.
ModelVO
// 确保更新后重新渲染
await
nextTick
()
if
(
processDesigner
.
value
?.
refresh
)
{
processDesigner
.
value
.
refresh
()
}
}
}
// 监听key和name的变化
watch
([()
=>
props
.
modelKey
,
()
=>
props
.
modelName
],
async
([
newKey
,
newName
])
=>
{
if
(
!
props
.
modelId
&&
newKey
&&
newName
&&
modeler
.
value
)
{
await
updateModelData
(
newKey
,
newName
)
}
}
model
.
value
=
{
},
{
immediate
:
true
,
deep
:
true
})
...
data
,
bpmnXml
:
undefined
// 清空 bpmnXml 属性
// 在组件卸载时清理
onBeforeUnmount
(()
=>
{
isModelerReady
.
value
=
false
modeler
.
value
=
null
// 清理全局实例
const
w
=
window
as
any
if
(
w
.
bpmnInstances
)
{
w
.
bpmnInstances
=
null
}
}
xmlString
.
value
=
data
.
bpmnXml
})
})
</
script
>
</
script
>
<
style
lang=
"scss"
>
<
style
lang=
"scss"
>
...
...
src/views/bpm/model/index.vue
View file @
9685fbf8
...
@@ -106,6 +106,7 @@ import CategoryDraggableModel from './CategoryDraggableModel.vue'
...
@@ -106,6 +106,7 @@ import CategoryDraggableModel from './CategoryDraggableModel.vue'
defineOptions
({
name
:
'BpmModel'
})
defineOptions
({
name
:
'BpmModel'
})
const
{
push
}
=
useRouter
()
const
message
=
useMessage
()
// 消息弹窗
const
message
=
useMessage
()
// 消息弹窗
const
loading
=
ref
(
true
)
// 列表的加载中
const
loading
=
ref
(
true
)
// 列表的加载中
const
isCategorySorting
=
ref
(
false
)
// 是否 category 正处于排序状态
const
isCategorySorting
=
ref
(
false
)
// 是否 category 正处于排序状态
...
@@ -124,7 +125,11 @@ const handleQuery = () => {
...
@@ -124,7 +125,11 @@ const handleQuery = () => {
/** 添加/修改操作 */
/** 添加/修改操作 */
const
formRef
=
ref
()
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
if
(
type
===
'create'
)
{
push
(
'/bpm/manager/model/create-update'
)
}
else
{
push
(
`/bpm/manager/model/create-update?id=
${
id
}
`
)
}
}
}
/** 流程表单的详情按钮操作 */
/** 流程表单的详情按钮操作 */
...
...
src/views/bpm/simple/SimpleModelDesign.vue
View file @
9685fbf8
<
template
>
<
template
>
<ContentWrap
:bodyStyle=
"
{ padding: '20px 16px' }">
<ContentWrap
:bodyStyle=
"
{ padding: '20px 16px' }">
<SimpleProcessDesigner
:model-id=
"modelId"
@
success=
"close"
/>
<SimpleProcessDesigner
:model-id=
"modelId"
:model-key=
"modelKey"
:model-name=
"modelName"
@
success=
"handleSuccess"
ref=
"designerRef"
/>
</ContentWrap>
</ContentWrap>
</
template
>
</
template
>
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
...
@@ -9,11 +15,26 @@ import { SimpleProcessDesigner } from '@/components/SimpleProcessDesignerV2/src/
...
@@ -9,11 +15,26 @@ import { SimpleProcessDesigner } from '@/components/SimpleProcessDesignerV2/src/
defineOptions
({
defineOptions
({
name
:
'SimpleModelDesign'
name
:
'SimpleModelDesign'
})
})
const
router
=
useRouter
()
// 路由
const
{
query
}
=
useRoute
()
// 路由的查询
const
props
=
defineProps
<
{
const
modelId
=
query
.
modelId
as
string
modelId
?:
string
const
close
=
()
=>
{
modelKey
?:
string
router
.
push
({
path
:
'/bpm/manager/model'
})
modelName
?:
string
}
>
()
const
emit
=
defineEmits
([
'success'
])
const
designerRef
=
ref
()
// 监听属性变化
watch
([()
=>
props
.
modelKey
,
()
=>
props
.
modelName
],
([
newKey
,
newName
])
=>
{
if
(
designerRef
.
value
&&
newKey
&&
newName
)
{
designerRef
.
value
.
updateModel
(
newKey
,
newName
)
}
},
{
immediate
:
true
,
deep
:
true
})
// 修改成功回调
const
handleSuccess
=
(
data
?:
any
)
=>
{
emit
(
'success'
,
data
)
}
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
<
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