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
9459a729
authored
Dec 09, 2024
by
GoldenZqqqq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 流程模型新增/修改/设计合为一个页面基本切换tab逻辑校验与页面样式优化
parent
5063db47
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
179 additions
and
85 deletions
+179
-85
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
+46
-23
src/views/bpm/model/CategoryDraggableModel.vue
+1
-1
src/views/bpm/model/CreateUpdate.vue
+60
-26
src/views/bpm/model/editor/index.vue
+61
-31
src/views/bpm/simple/SimpleModelDesign.vue
+11
-4
No files found.
src/components/SimpleProcessDesignerV2/src/SimpleProcessDesigner.vue
View file @
9459a729
...
...
@@ -38,12 +38,21 @@ import * as UserGroupApi from '@/api/bpm/userGroup'
defineOptions
({
name
:
'SimpleProcessDesigner'
})
const
emits
=
defineEmits
([
'success'
])
// 保存成功事件
const
props
=
defineProps
({
modelId
:
{
type
:
String
,
required
:
true
required
:
false
},
modelKey
:
{
type
:
String
,
required
:
false
},
modelName
:
{
type
:
String
,
required
:
false
}
})
...
...
@@ -69,6 +78,7 @@ const message = useMessage() // 国际化
const
processNodeTree
=
ref
<
SimpleFlowNode
|
undefined
>
()
const
errorDialogVisible
=
ref
(
false
)
let
errorNodes
:
SimpleFlowNode
[]
=
[]
const
saveSimpleFlowModel
=
async
(
simpleModelNode
:
SimpleFlowNode
)
=>
{
if
(
!
simpleModelNode
)
{
message
.
error
(
'模型数据为空'
)
...
...
@@ -76,21 +86,28 @@ const saveSimpleFlowModel = async (simpleModelNode: SimpleFlowNode) => {
}
try
{
loading
.
value
=
true
const
data
=
{
id
:
props
.
modelId
,
simpleModel
:
simpleModelNode
}
const
result
=
await
updateBpmSimpleModel
(
data
)
if
(
result
)
{
message
.
success
(
'修改成功'
)
emits
(
'success'
)
if
(
props
.
modelId
)
{
// 编辑模式
const
data
=
{
id
:
props
.
modelId
,
simpleModel
:
simpleModelNode
}
const
result
=
await
updateBpmSimpleModel
(
data
)
if
(
result
)
{
message
.
success
(
'修改成功'
)
emits
(
'success'
)
}
else
{
message
.
alert
(
'修改失败'
)
}
}
else
{
message
.
alert
(
'修改失败'
)
// 新建模式,直接返回数据
emits
(
'success'
,
simpleModelNode
)
}
}
finally
{
loading
.
value
=
false
}
}
// 校验节点设置。 暂时以 showText 为空 未节点错误配置
const
validateNode
=
(
node
:
SimpleFlowNode
|
undefined
,
errorNodes
:
SimpleFlowNode
[])
=>
{
if
(
node
)
{
...
...
@@ -134,12 +151,14 @@ onMounted(async () => {
try
{
loading
.
value
=
true
// 获取表单字段
const
bpmnModel
=
await
getModel
(
props
.
modelId
)
if
(
bpmnModel
)
{
formType
.
value
=
bpmnModel
.
formType
if
(
formType
.
value
===
10
)
{
const
bpmnForm
=
(
await
getForm
(
bpmnModel
.
formId
))
as
unknown
as
FormVO
formFields
.
value
=
bpmnForm
?.
fields
if
(
props
.
modelId
)
{
const
bpmnModel
=
await
getModel
(
props
.
modelId
)
if
(
bpmnModel
)
{
formType
.
value
=
bpmnModel
.
formType
if
(
formType
.
value
===
10
)
{
const
bpmnForm
=
(
await
getForm
(
bpmnModel
.
formId
))
as
unknown
as
FormVO
formFields
.
value
=
bpmnForm
?.
fields
}
}
}
// 获得角色列表
...
...
@@ -155,14 +174,18 @@ onMounted(async () => {
// 获取用户组列表
userGroupOptions
.
value
=
await
UserGroupApi
.
getUserGroupSimpleList
()
//获取 SIMPLE 设计器模型
const
result
=
await
getBpmSimpleModel
(
props
.
modelId
)
if
(
result
)
{
processNodeTree
.
value
=
result
}
else
{
// 初始值
if
(
props
.
modelId
)
{
//获取 SIMPLE 设计器模型
const
result
=
await
getBpmSimpleModel
(
props
.
modelId
)
if
(
result
)
{
processNodeTree
.
value
=
result
}
}
// 如果没有现有模型,创建初始模型
if
(
!
processNodeTree
.
value
)
{
processNodeTree
.
value
=
{
name
:
'发起人'
,
name
:
props
.
modelName
||
'发起人'
,
type
:
NodeType
.
START_USER_NODE
,
id
:
NodeId
.
START_USER_NODE_ID
,
childNode
:
{
...
...
src/views/bpm/model/CategoryDraggableModel.vue
View file @
9459a729
...
...
@@ -249,7 +249,7 @@ import { formatDate } from '@/utils/formatTime'
import
*
as
ModelApi
from
'@/api/bpm/model'
import
*
as
FormApi
from
'@/api/bpm/form'
import
{
setConfAndFields2
}
from
'@/utils/formCreate'
import
{
BpmModelFormType
,
BpmModelType
}
from
'@/utils/constants'
import
{
BpmModelFormType
}
from
'@/utils/constants'
import
{
checkPermi
}
from
'@/utils/permission'
import
{
useUserStoreWithOut
}
from
'@/store/modules/user'
import
{
useAppStore
}
from
'@/store/modules/app'
...
...
src/views/bpm/model/CreateUpdate.vue
View file @
9459a729
<
template
>
<!-- 头部导航栏 -->
<div
class=
"absolute top-0 left-0 right-0 h-50px bg-white border-bottom z-10 flex items-center
justify-between
px-20px"
class=
"absolute top-0 left-0 right-0 h-50px bg-white border-bottom z-10 flex items-center px-20px"
>
<div
class=
"flex items-center"
>
<Icon
icon=
"ep:arrow-left"
class=
"cursor-pointer"
@
click=
"router.back()"
/>
<span
class=
"ml-10px text-16px"
>
{{
formData
.
name
||
'创建流程'
}}
</span>
<!-- 左侧标题,固定宽度 -->
<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
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=
"currentStep = index"
>
<div
class=
"w-400px flex items-center justify-between h-full"
>
<div
class=
"w-28px h-28px rounded-full flex items-center justify-center mr-8px border-2 border-solid text-15px"
v-for=
"(step, index) in steps"
:key=
"index"
class=
"flex items-center cursor-pointer mx-15px relative h-full"
:class=
"[
currentStep === index
? '
bg-[#3473ff] text-white
'
: '
border-gray-300 bg-white
text-gray-500'
? '
text-[#3473ff] border-[#3473ff] border-b-2 border-b-solid
'
: 'text-gray-500'
]"
@
click=
"handleStepClick(index)"
>
{{
index
+
1
}}
<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>
<span
class=
"text-16px font-bold"
>
{{
step
.
title
}}
</span>
</div>
</div>
<!--
操作按钮
-->
<div
class=
"
flex items-center gap-1
"
>
<!--
右侧按钮,固定宽度
-->
<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>
...
...
@@ -264,15 +269,26 @@
</el-form>
</div>
<!-- 第三步:流程设计 -->
<div
v-show=
"currentStep === 2"
>
<!-- BPMN设计器 -->
<template
v-if=
"formData.type === BpmModelType.BPMN"
>
<BpmModelEditor
:model-id=
"formData.id"
@
success=
"handleDesignSuccess"
/>
<BpmModelEditor
:model-id=
"formData.id"
:model-key=
"formData.key"
:model-name=
"formData.name"
@
success=
"handleDesignSuccess"
/>
</
template
>
<!-- Simple设计器 -->
<
template
v-else
>
<SimpleModelDesign
:model-id=
"formData.id"
@
success=
"handleDesignSuccess"
/>
<SimpleModelDesign
:model-id=
"formData.id"
:model-key=
"formData.key"
:model-name=
"formData.name"
@
success=
"handleDesignSuccess"
/>
</
template
>
</div>
</ContentWrap>
...
...
@@ -520,9 +536,27 @@ const steps = [
]
// 处理设计器保存成功
const
handleDesignSuccess
=
()
=>
{
const
handleDesignSuccess
=
(
bpmnXml
?:
string
)
=>
{
if
(
bpmnXml
)
{
// 新建时,保存设计器生成的XML
formData
.
value
.
bpmnXml
=
bpmnXml
}
message
.
success
(
'保存成功'
)
}
// 步骤切换处理
const
handleStepClick
=
async
(
index
:
number
)
=>
{
// 如果是切换到第三步(流程设计),需要校验key和name
if
(
index
===
2
&&
!
formData
.
value
.
id
)
{
// 新增时才校验
if
(
!
formData
.
value
.
key
||
!
formData
.
value
.
name
)
{
message
.
warning
(
'请先填写流程标识和流程名称'
)
return
}
}
currentStep
.
value
=
index
}
</
script
>
<
style
lang=
"scss"
scoped
>
...
...
src/views/bpm/model/editor/index.vue
View file @
9459a729
...
...
@@ -11,6 +11,7 @@
ref=
"processDesigner"
@
init-finished=
"initModeler"
:additionalModel=
"controlForm.additionalModel"
:model=
"model"
@
save=
"save"
/>
<!-- 流程属性器,负责编辑每个流程节点的属性 -->
...
...
@@ -35,14 +36,15 @@ import * as ModelApi from '@/api/bpm/model'
defineOptions
({
name
:
'BpmModelEditor'
})
const
props
=
defineProps
<
{
modelId
:
string
modelId
?:
string
modelKey
?:
string
modelName
?:
string
}
>
()
const
emit
=
defineEmits
([
'success'
])
const
router
=
useRouter
()
// 路由
const
{
query
}
=
useRoute
()
// 路由的查询
const
message
=
useMessage
()
// 国际化
const
xmlString
=
ref
(
undefined
)
// BPMN XML
const
xmlString
=
ref
<
string
>
(
)
// BPMN XML
const
modeler
=
ref
(
null
)
// BPMN Modeler
const
controlForm
=
ref
({
simulation
:
true
,
...
...
@@ -61,16 +63,32 @@ const initModeler = (item) => {
},
10
)
}
/** 获取默认的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
)
=>
{
try
{
const
data
=
{
...
model
.
value
,
bpmnXml
:
bpmnXml
}
as
unknown
as
ModelApi
.
ModelVO
// 提交
await
ModelApi
.
updateModelBpmn
(
data
)
emit
(
'success'
)
if
(
props
.
modelId
)
{
// 编辑模式
const
data
=
{
...
model
.
value
,
bpmnXml
:
bpmnXml
}
as
unknown
as
ModelApi
.
ModelVO
await
ModelApi
.
updateModelBpmn
(
data
)
emit
(
'success'
)
}
else
{
// 新建模式,直接返回XML
emit
(
'success'
,
bpmnXml
)
}
}
catch
(
error
)
{
console
.
error
(
'保存失败:'
,
error
)
message
.
error
(
'保存失败'
)
...
...
@@ -79,28 +97,40 @@ const save = async (bpmnXml: string) => {
/** 初始化 */
onMounted
(
async
()
=>
{
if
(
!
props
.
modelId
)
{
message
.
error
(
'缺少模型 modelId 编号'
)
return
if
(
props
.
modelId
)
{
// 编辑模式
try
{
// 查询模型
const
data
=
await
ModelApi
.
getModel
(
props
.
modelId
)
model
.
value
=
{
...
data
,
bpmnXml
:
undefined
// 清空 bpmnXml 属性
}
xmlString
.
value
=
data
.
bpmnXml
||
getDefaultBpmnXml
(
data
.
key
,
data
.
name
)
}
catch
(
error
)
{
console
.
error
(
'获取模型失败:'
,
error
)
message
.
error
(
'获取模型失败'
)
}
}
else
if
(
props
.
modelKey
&&
props
.
modelName
)
{
// 新建模式,使用传入的key和name创建默认XML
xmlString
.
value
=
getDefaultBpmnXml
(
props
.
modelKey
,
props
.
modelName
)
model
.
value
=
{
key
:
props
.
modelKey
,
name
:
props
.
modelName
}
as
ModelApi
.
ModelVO
}
// 查询模型
const
data
=
await
ModelApi
.
getModel
(
String
(
props
.
modelId
))
if
(
!
data
.
bpmnXml
)
{
// 首次创建的 Model 模型,它是没有 bpmnXml,此时需要给它一个默认的
data
.
bpmnXml
=
` <?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="
${
data
.
key
}
" name="
${
data
.
name
}
" isExecutable="true" />
<bpmndi:BPMNDiagram id="BPMNDiagram">
<bpmndi:BPMNPlane id="
${
data
.
key
}
_di" bpmnElement="
${
data
.
key
}
" />
</bpmndi:BPMNDiagram>
</definitions>`
}
model
.
value
=
{
...
data
,
bpmnXml
:
undefined
// 清空 bpmnXml 属性
}
xmlString
.
value
=
data
.
bpmnXml
})
// 监听key和name的变化
watch
([()
=>
props
.
modelKey
,
()
=>
props
.
modelName
],
([
newKey
,
newName
])
=>
{
if
(
!
props
.
modelId
&&
newKey
&&
newName
)
{
xmlString
.
value
=
getDefaultBpmnXml
(
newKey
,
newName
)
model
.
value
=
{
key
:
newKey
,
name
:
newName
}
as
ModelApi
.
ModelVO
}
},
{
immediate
:
true
})
</
script
>
<
style
lang=
"scss"
>
.process-panel__container
{
...
...
src/views/bpm/simple/SimpleModelDesign.vue
View file @
9459a729
<
template
>
<ContentWrap
:bodyStyle=
"
{ padding: '20px 16px' }">
<SimpleProcessDesigner
:model-id=
"modelId"
@
success=
"handleSuccess"
/>
<SimpleProcessDesigner
:model-id=
"modelId"
:model-key=
"modelKey"
:model-name=
"modelName"
@
success=
"handleSuccess"
/>
</ContentWrap>
</
template
>
<
script
setup
lang=
"ts"
>
...
...
@@ -11,14 +16,16 @@ defineOptions({
})
defineProps
<
{
modelId
:
string
modelId
?:
string
modelKey
?:
string
modelName
?:
string
}
>
()
const
emit
=
defineEmits
([
'success'
])
// 修改成功回调
const
handleSuccess
=
()
=>
{
emit
(
'success'
)
const
handleSuccess
=
(
data
?:
any
)
=>
{
emit
(
'success'
,
data
)
}
</
script
>
<
style
lang=
"scss"
scoped
></
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment