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
1854b85b
authored
Mar 26, 2023
by
YunaiV
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Vue3 重构:流程模型的列表和新增、修改
parent
d0ed5edb
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
416 additions
and
649 deletions
+416
-649
src/api/bpm/model/index.ts
+3
-3
src/components/DictTag/src/DictTag.vue
+1
-1
src/views/bpm/model/ModelForm.vue
+219
-0
src/views/bpm/model/editor/index.vue
+2
-2
src/views/bpm/model/index.vue
+191
-537
src/views/bpm/model/model.data.ts
+0
-106
No files found.
src/api/bpm/model/index.ts
View file @
1854b85b
...
...
@@ -25,7 +25,7 @@ export type ModelVO = {
bpmnXml
:
string
}
export
const
getModelPage
Api
=
async
(
params
)
=>
{
export
const
getModelPage
=
async
(
params
)
=>
{
return
await
request
.
get
({
url
:
'/bpm/model/page'
,
params
})
}
...
...
@@ -33,7 +33,7 @@ export const getModel = async (id: number) => {
return
await
request
.
get
({
url
:
'/bpm/model/get?id='
+
id
})
}
export
const
updateModel
Api
=
async
(
data
:
ModelVO
)
=>
{
export
const
updateModel
=
async
(
data
:
ModelVO
)
=>
{
return
await
request
.
put
({
url
:
'/bpm/model/update'
,
data
:
data
})
}
...
...
@@ -46,7 +46,7 @@ export const updateModelStateApi = async (id: number, state: number) => {
return
await
request
.
put
({
url
:
'/bpm/model/update-state'
,
data
:
data
})
}
export
const
createModel
Api
=
async
(
data
:
ModelVO
)
=>
{
export
const
createModel
=
async
(
data
:
ModelVO
)
=>
{
return
await
request
.
post
({
url
:
'/bpm/model/create'
,
data
:
data
})
}
...
...
src/components/DictTag/src/DictTag.vue
View file @
1854b85b
...
...
@@ -34,7 +34,7 @@ export default defineComponent({
return
null
}
// 解决自定义字典标签值为零时标签不渲染的问题
if
(
props
.
value
===
undefined
)
{
if
(
props
.
value
===
undefined
||
props
.
value
===
null
)
{
return
null
}
getDictObj
(
props
.
type
,
props
.
value
.
toString
())
...
...
src/views/bpm/model/ModelForm.vue
0 → 100644
View file @
1854b85b
<
template
>
<Dialog
:title=
"modelTitle"
v-model=
"modelVisible"
width=
"600"
>
<el-form
ref=
"formRef"
:model=
"formData"
:rules=
"formRules"
label-width=
"110px"
v-loading=
"formLoading"
>
<el-form-item
label=
"流程标识"
prop=
"key"
>
<el-input
v-model=
"formData.key"
placeholder=
"请输入流标标识"
style=
"width: 330px"
:disabled=
"!!formData.id"
/>
<el-tooltip
v-if=
"!formData.id"
class=
"item"
effect=
"light"
content=
"新建后,流程标识不可修改!"
placement=
"top"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</el-tooltip>
<el-tooltip
v-else
class=
"item"
effect=
"light"
content=
"流程标识不可修改!"
placement=
"top"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</el-tooltip>
</el-form-item>
<el-form-item
label=
"流程名称"
prop=
"name"
>
<el-input
v-model=
"formData.name"
placeholder=
"请输入流程名称"
:disabled=
"!!formData.id"
clearable
/>
</el-form-item>
<el-form-item
v-if=
"formData.id"
label=
"流程分类"
prop=
"category"
>
<el-select
v-model=
"formData.category"
placeholder=
"请选择流程分类"
clearable
style=
"width: 100%"
>
<el-option
v-for=
"dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_CATEGORY)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"流程描述"
prop=
"description"
>
<el-input
type=
"textarea"
v-model=
"formData.description"
clearable
/>
</el-form-item>
<div
v-if=
"formData.id"
>
<el-form-item
label=
"表单类型"
prop=
"formType"
>
<el-radio-group
v-model=
"formData.formType"
>
<el-radio
v-for=
"dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_FORM_TYPE)"
:key=
"dict.value"
:label=
"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 forms"
: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"
effect=
"light"
content=
"自定义表单的提交路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/create"
placement=
"top"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</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"
effect=
"light"
content=
"自定义表单的查看路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/view"
placement=
"top"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</el-tooltip>
</el-form-item>
</div>
</el-form>
<template
#
footer
>
<el-button
@
click=
"submitForm"
type=
"primary"
:disabled=
"formLoading"
>
确 定
</el-button>
<el-button
@
click=
"modelVisible = false"
>
取 消
</el-button>
</
template
>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
ElMessageBox
}
from
'element-plus'
import
*
as
ModelApi
from
'@/api/bpm/model'
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
modelVisible
=
ref
(
false
)
// 弹窗的是否展示
const
modelTitle
=
ref
(
''
)
// 弹窗的标题
const
formLoading
=
ref
(
false
)
// 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
const
formType
=
ref
(
''
)
// 表单的类型:create - 新增;update - 修改
const
formData
=
ref
({
formType
:
10
,
name
:
''
,
category
:
undefined
,
description
:
''
,
formId
:
''
,
formCustomCreatePath
:
''
,
formCustomViewPath
:
''
})
const
formRules
=
reactive
({
category
:
[{
required
:
true
,
message
:
'参数分类不能为空'
,
trigger
:
'blur'
}],
name
:
[{
required
:
true
,
message
:
'参数名称不能为空'
,
trigger
:
'blur'
}],
key
:
[{
required
:
true
,
message
:
'参数键名不能为空'
,
trigger
:
'blur'
}],
value
:
[{
required
:
true
,
message
:
'参数键值不能为空'
,
trigger
:
'blur'
}],
visible
:
[{
required
:
true
,
message
:
'是否可见不能为空'
,
trigger
:
'blur'
}]
})
const
formRef
=
ref
()
// 表单 Ref
/** 打开弹窗 */
const
open
=
async
(
type
:
string
,
id
?:
number
)
=>
{
modelVisible
.
value
=
true
modelTitle
.
value
=
t
(
'action.'
+
type
)
formType
.
value
=
type
resetForm
()
// 修改时,设置数据
if
(
id
)
{
formLoading
.
value
=
true
try
{
formData
.
value
=
await
ModelApi
.
getModel
(
id
)
}
finally
{
formLoading
.
value
=
false
}
}
}
defineExpose
({
open
})
// 提供 open 方法,用于打开弹窗
/** 提交表单 */
const
emit
=
defineEmits
([
'success'
])
// 定义 success 事件,用于操作成功后的回调
const
submitForm
=
async
()
=>
{
// 校验表单
if
(
!
formRef
)
return
const
valid
=
await
formRef
.
value
.
validate
()
if
(
!
valid
)
return
// 提交请求
formLoading
.
value
=
true
try
{
const
data
=
formData
.
value
as
unknown
as
ModelApi
.
ModelVO
if
(
formType
.
value
===
'create'
)
{
await
ModelApi
.
createModel
(
data
)
// 提示,引导用户做后续的操作
await
ElMessageBox
.
alert
(
'
<
strong
>
新建模型成功!
<
/strong>后续需要执行如下 4 个步骤:'
+
'
<
div
>
1
.
点击【修改流程】按钮,配置流程的分类、表单信息
<
/div>'
+
'
<
div
>
2
.
点击【设计流程】按钮,绘制流程图
<
/div>'
+
'
<
div
>
3
.
点击【分配规则】按钮,设置每个用户任务的审批人
<
/div>'
+
'
<
div
>
4
.
点击【发布流程】按钮,完成流程的最终发布
<
/div>'
+
'另外,每次流程修改后,都需要点击【发布流程】按钮,才能正式生效!!!'
,
'重要提示'
,
{
dangerouslyUseHTMLString
:
true
,
type
:
'success'
}
)
}
else
{
await
ModelApi
.
updateModel
(
data
)
message
.
success
(
t
(
'common.updateSuccess'
))
}
modelVisible
.
value
=
false
// 发送操作成功的事件
emit
(
'success'
)
}
finally
{
formLoading
.
value
=
false
}
}
/** 重置表单 */
const
resetForm
=
()
=>
{
formData
.
value
=
{
formType
:
10
,
name
:
''
,
category
:
undefined
,
description
:
''
,
formId
:
''
,
formCustomCreatePath
:
''
,
formCustomViewPath
:
''
}
formRef
.
value
?.
resetFields
()
}
</
script
>
src/views/bpm/model/editor/index.vue
View file @
1854b85b
...
...
@@ -62,10 +62,10 @@ const save = async (bpmnXml) => {
}
as
unknown
as
ModelApi
.
ModelVO
// 提交
if
(
data
.
id
)
{
await
ModelApi
.
updateModel
Api
(
data
)
await
ModelApi
.
updateModel
(
data
)
message
.
success
(
'修改成功'
)
}
else
{
await
ModelApi
.
createModel
Api
(
data
)
await
ModelApi
.
createModel
(
data
)
message
.
success
(
'新增成功'
)
}
// 跳转回去
...
...
src/views/bpm/model/index.vue
View file @
1854b85b
<
template
>
<ContentWrap>
<!-- 列表 -->
<XTable
@
register=
"registerTable"
>
<template
#
toolbar_buttons
>
<!-- 操作:新增 -->
<XButton
type=
"primary"
preIcon=
"ep:zoom-in"
title=
"新建流程"
v-hasPermi=
"['bpm:model:create']"
@
click=
"handleCreate"
/>
<!-- 操作:导入 -->
<XButton
type=
"warning"
preIcon=
"ep:upload"
:title=
"'导入流程'"
@
click=
"handleImport"
style=
"margin-left: 10px"
/>
</
template
>
<!-- 流程名称 -->
<
template
#
name_default=
"{ row }"
>
<XTextButton
:title=
"row.name"
@
click=
"handleBpmnDetail(row.id)"
/>
</
template
>
<!-- 流程分类 -->
<
template
#
category_default=
"{ row }"
>
<DictTag
:type=
"DICT_TYPE.BPM_MODEL_CATEGORY"
:value=
"Number(row?.category)"
/>
</
template
>
<!-- 表单信息 -->
<
template
#
formId_default=
"{ row }"
>
<XTextButton
v-if=
"row.formType === 10"
:title=
"forms.find((form) => form.id === row.formId)?.name || row.formId"
@
click=
"handleFormDetail(row)"
/>
<XTextButton
v-else
:title=
"row.formCustomCreatePath"
@
click=
"handleFormDetail(row)"
/>
</
template
>
<!-- 流程版本 -->
<
template
#
version_default=
"{ row }"
>
<el-tag
v-if=
"row.processDefinition"
>
v
{{
row
.
processDefinition
.
version
}}
</el-tag>
<el-tag
type=
"warning"
v-else
>
未部署
</el-tag>
</
template
>
<!-- 激活状态 -->
<
template
#
status_default=
"{ row }"
>
<el-switch
v-if=
"row.processDefinition"
v-model=
"row.processDefinition.suspensionState"
:active-value=
"1"
:inactive-value=
"2"
@
change=
"handleChangeState(row)"
/>
</
template
>
<!-- 操作 -->
<
template
#
actionbtns_default=
"{ row }"
>
<XTextButton
preIcon=
"ep:edit"
title=
"修改流程"
v-hasPermi=
"['bpm:model:update']"
@
click=
"handleUpdate(row.id)"
/>
<XTextButton
preIcon=
"ep:setting"
title=
"设计流程"
v-hasPermi=
"['bpm:model:update']"
@
click=
"handleDesign(row)"
/>
<XTextButton
preIcon=
"ep:user"
title=
"分配规则"
v-hasPermi=
"['bpm:task-assign-rule:query']"
@
click=
"handleAssignRule(row)"
/>
<XTextButton
preIcon=
"ep:position"
title=
"发布流程"
v-hasPermi=
"['bpm:model:deploy']"
@
click=
"handleDeploy(row)"
/>
<XTextButton
preIcon=
"ep:aim"
title=
"流程定义"
v-hasPermi=
"['bpm:process-definition:query']"
@
click=
"handleDefinitionList(row)"
/>
<!-- 操作:删除 -->
<XTextButton
preIcon=
"ep:delete"
:title=
"t('action.del')"
v-hasPermi=
"['bpm:model:delete']"
@
click=
"handleDelete(row.id)"
/>
</
template
>
</XTable>
<!-- 对话框(添加 / 修改流程) -->
<XModal
v-model=
"dialogVisible"
:title=
"dialogTitle"
width=
"600"
>
<!-- 搜索工作栏 -->
<el-form
:loading=
"dialogLoading"
el-form
ref=
"saveFormRef"
:model=
"saveForm"
:rules=
"rules"
label-width=
"110px"
class=
"-mb-15px"
:model=
"queryParams"
ref=
"queryFormRef"
:inline=
"true"
label-width=
"68px"
>
<el-form-item
label=
"流程标识"
prop=
"key"
>
<el-input
v-model=
"saveForm.key"
placeholder=
"请输入流标标识"
style=
"width: 330px"
:disabled=
"!!saveForm.id"
v-model=
"queryParams.key"
placeholder=
"请输入流程标识"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
<el-tooltip
v-if=
"!saveForm.id"
class=
"item"
effect=
"light"
content=
"新建后,流程标识不可修改!"
placement=
"top"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</el-tooltip>
<el-tooltip
v-else
class=
"item"
effect=
"light"
content=
"流程标识不可修改!"
placement=
"top"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</el-tooltip>
</el-form-item>
<el-form-item
label=
"流程名称"
prop=
"name"
>
<el-input
v-model=
"saveForm
.name"
v-model=
"queryParams
.name"
placeholder=
"请输入流程名称"
:disabled=
"!!saveForm.id"
clearable
@
keyup
.
enter=
"handleQuery"
class=
"!w-240px"
/>
</el-form-item>
<el-form-item
v-if=
"saveForm.id"
label=
"流程分类"
prop=
"category"
>
<el-form-item
label=
"流程分类"
prop=
"category"
>
<el-select
v-model=
"saveForm
.category"
v-model=
"queryParams
.category"
placeholder=
"请选择流程分类"
clearable
style=
"width: 100%
"
class=
"!w-240px
"
>
<el-option
v-for=
"dict in ge
tDictOptions(DICT_TYPE.BPM_MODEL_CATEGORY)"
v-for=
"dict in getIn
tDictOptions(DICT_TYPE.BPM_MODEL_CATEGORY)"
:key=
"dict.value"
:label=
"dict.label"
:value=
"dict.value"
/>
</el-select>
</el-form-item>
<el-form-item
label=
"流程描述"
prop=
"description"
>
<el-input
type=
"textarea"
v-model=
"saveForm.description"
clearable
/>
</el-form-item>
<div
v-if=
"saveForm.id"
>
<el-form-item
label=
"表单类型"
prop=
"formType"
>
<el-radio-group
v-model=
"saveForm.formType"
>
<el-radio
v-for=
"dict in getDictOptions(DICT_TYPE.BPM_MODEL_FORM_TYPE)"
:key=
"parseInt(dict.value)"
:label=
"parseInt(dict.value)"
<el-form-item>
<el-button
@
click=
"handleQuery"
><Icon
icon=
"ep:search"
class=
"mr-5px"
/>
搜索
</el-button>
<el-button
@
click=
"resetQuery"
><Icon
icon=
"ep:refresh"
class=
"mr-5px"
/>
重置
</el-button>
<el-button
type=
"primary"
plain
@
click=
"openForm('create')"
v-hasPermi=
"['bpm:model:create']"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if=
"saveForm.formType === 10"
label=
"流程表单"
prop=
"formId"
>
<el-select
v-model=
"saveForm.formId"
clearable
style=
"width: 100%"
>
<el-option
v-for=
"form in forms"
:key=
"form.id"
:label=
"form.name"
:value=
"form.id"
/>
</el-select>
<Icon
icon=
"ep:plus"
class=
"mr-5px"
/>
新建流程
</el-button>
<el-button
type=
"success"
plain
@
click=
"handleImport()"
v-hasPermi=
"['bpm:model:import']"
>
<Icon
icon=
"ep:upload"
class=
"mr-5px"
/>
导入流程
</el-button>
</el-form-item>
<el-form-item
v-if=
"saveForm.formType === 20"
label=
"表单提交路由"
prop=
"formCustomCreatePath"
>
<el-input
v-model=
"saveForm.formCustomCreatePath"
placeholder=
"请输入表单提交路由"
style=
"width: 330px"
/>
<el-tooltip
class=
"item"
effect=
"light"
content=
"自定义表单的提交路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/create"
placement=
"top"
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading=
"loading"
:data=
"list"
>
<el-table-column
label=
"流程标识"
align=
"center"
prop=
"key"
/>
<el-table-column
label=
"流程名称"
align=
"center"
prop=
"name"
width=
"200"
>
<template
#
default=
"scope"
>
<el-button
type=
"text"
@
click=
"handleBpmnDetail(scope.row)"
>
<span>
{{
scope
.
row
.
name
}}
</span>
</el-button>
</
template
>
</el-table-column>
<el-table-column
label=
"流程分类"
align=
"center"
prop=
"category"
width=
"100"
>
<
template
#
default=
"scope"
>
<dict-tag
:type=
"DICT_TYPE.BPM_MODEL_CATEGORY"
:value=
"scope.row.category"
/>
</
template
>
</el-table-column>
<el-table-column
label=
"表单信息"
align=
"center"
prop=
"formType"
width=
"200"
>
<
template
#
default=
"scope"
>
<el-button
v-if=
"scope.row.formId"
type=
"text"
@
click=
"handleFormDetail(scope.row)"
>
<span>
{{
scope
.
row
.
formName
}}
</span>
</el-button>
<el-button
v-else-if=
"scope.row.formCustomCreatePath"
type=
"text"
@
click=
"handleFormDetail(scope.row)"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</el-tooltip>
</el-form-item>
<el-form-item
v-if=
"saveForm.formType === 20"
label=
"表单查看路由"
prop=
"formCustomViewPath"
<span>
{{
scope
.
row
.
formCustomCreatePath
}}
</span>
</el-button>
<label
v-else
>
暂无表单
</label>
</
template
>
</el-table-column>
<el-table-column
label=
"创建时间"
align=
"center"
prop=
"createTime"
:formatter=
"dateFormatter"
/>
<el-table-column
label=
"最新部署的流程定义"
align=
"center"
>
<el-table-column
label=
"流程版本"
align=
"center"
prop=
"processDefinition.version"
width=
"100"
>
<el-input
v-model=
"saveForm.formCustomViewPath"
placeholder=
"请输入表单查看路由"
style=
"width: 330px"
/>
<el-tooltip
class=
"item"
effect=
"light"
content=
"自定义表单的查看路径,使用 Vue 的路由地址,例如说:bpm/oa/leave/view"
placement=
"top"
<
template
#
default=
"scope"
>
<el-tag
v-if=
"scope.row.processDefinition"
>
v
{{
scope
.
row
.
processDefinition
.
version
}}
</el-tag>
<el-tag
v-else
type=
"warning"
>
未部署
</el-tag>
</
template
>
</el-table-column>
<el-table-column
label=
"激活状态"
align=
"center"
prop=
"processDefinition.version"
width=
"80"
>
<i
style=
"padding-left: 5px"
class=
"el-icon-question"
></i>
</el-tooltip>
</el-form-item>
</div>
</el-form>
<
template
#
footer
>
<!-- 按钮:保存 -->
<XButton
type=
"primary"
:loading=
"dialogLoading"
@
click=
"submitForm"
:title=
"t('action.save')"
/>
<!-- 按钮:关闭 -->
<XButton
:loading=
"dialogLoading"
@
click=
"dialogVisible = false"
:title=
"t('dialog.close')"
<
template
#
default=
"scope"
>
<el-switch
v-if=
"scope.row.processDefinition"
v-model=
"scope.row.processDefinition.suspensionState"
:active-value=
"1"
:inactive-value=
"2"
@
change=
"handleChangeState(scope.row)"
/>
</
template
>
</XModal>
<!-- 导入流程 -->
<XModal
v-model=
"importDialogVisible"
width=
"400"
title=
"导入流程"
>
<div>
<el-upload
ref=
"uploadRef"
:action=
"importUrl"
:headers=
"uploadHeaders"
:drag=
"true"
:limit=
"1"
:multiple=
"true"
:show-file-list=
"true"
:disabled=
"uploadDisabled"
:on-exceed=
"handleExceed"
:on-success=
"handleFileSuccess"
:on-error=
"excelUploadError"
:auto-upload=
"false"
accept=
".bpmn, .xml"
name=
"bpmnFile"
:data=
"importForm"
</el-table-column>
<el-table-column
label=
"部署时间"
align=
"center"
prop=
"deploymentTime"
width=
"180"
>
<
template
#
default=
"scope"
>
<span
v-if=
"scope.row.processDefinition"
>
{{
formatDate
(
scope
.
row
.
processDefinition
.
deploymentTime
)
}}
</span>
</
template
>
</el-table-column>
</el-table-column>
<el-table-column
label=
"操作"
align=
"center"
fixed=
"right"
class-name=
"fixed-width"
>
<
template
#
default=
"scope"
>
<el-button
link
type=
"primary"
@
click=
"openForm('update', scope.row.id)"
v-hasPermi=
"['bpm:model:update']"
>
<Icon
class=
"el-icon--upload"
icon=
"ep:upload-filled"
/>
<div
class=
"el-upload__text"
>
将文件拖到此处,或
<em>
点击上传
</em>
</div>
<
template
#
tip
>
<div
class=
"el-upload__tip"
style=
"color: red"
>
提示:仅允许导入“bpm”或“xml”格式文件!
</div>
<div>
<el-form
ref=
"importFormRef"
:model=
"importForm"
:rules=
"rules"
label-width=
"120px"
status-icon
修改流程
</el-button>
<!-- TODO tailow 了-->
<el-button
link
@
click=
"openDetail(scope.row.id)"
v-hasPermi=
"['bpm:form:query']"
>
详情
</el-button>
<el-button
link
type=
"danger"
@
click=
"handleDelete(scope.row.id)"
v-hasPermi=
"['bpm:form:delete']"
>
<el-form-item
label=
"流程标识"
prop=
"key"
>
<el-input
v-model=
"importForm.key"
placeholder=
"请输入流标标识"
style=
"width: 250px"
/>
</el-form-item>
<el-form-item
label=
"流程名称"
prop=
"name"
>
<el-input
v-model=
"importForm.name"
placeholder=
"请输入流程名称"
clearable
/>
</el-form-item>
<el-form-item
label=
"流程描述"
prop=
"description"
>
<el-input
type=
"textarea"
v-model=
"importForm.description"
clearable
/>
</el-form-item>
</el-form>
</div>
删除
</el-button>
</
template
>
</el-upload>
</div>
<
template
#
footer
>
<!-- 按钮:保存 -->
<XButton
type=
"warning"
preIcon=
"ep:upload-filled"
:title=
"t('action.save')"
@
click=
"submitFileForm"
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total=
"total"
v-model:page=
"queryParams.pageNo"
v-model:limit=
"queryParams.pageSize"
@
pagination=
"getList"
/>
<XButton
title=
"取 消"
@
click=
"uploadClose"
/>
</
template
>
</XModal>
</ContentWrap>
<!-- 表单详情的弹窗 -->
<XModal
v-model=
"formDetailVisible"
width=
"800"
title=
"表单详情"
:show-footer=
"false"
>
<form-create
:rule=
"formDetailPreview.rule"
:option=
"formDetailPreview.option"
v-if=
"formDetailVisible"
/>
</XModal>
<!-- 表单弹窗:添加/修改 -->
<ModelForm
ref=
"formRef"
@
success=
"getList"
/>
<!-- 流程模型图的预览 -->
<XModal
title=
"流程图"
v-model=
"showBpmnOpen"
width=
"80%"
height=
"90%"
>
<my-process-viewer
key=
"designer"
v-model=
"bpmnXML"
:value=
"bpmnXML"
v-bind=
"bpmnControlForm"
:prefix=
"bpmnControlForm.prefix"
/>
</XModal>
</ContentWrap>
<!-- 表单详情的弹窗 -->
<Dialog
title=
"表单详情"
v-model=
"detailVisible"
width=
"800"
>
<form-create
:rule=
"detailData.rule"
:option=
"detailData.option"
/>
</Dialog>
</template>
<
script
setup
lang=
"ts"
>
// 全局相关的 import
import
{
DICT_TYPE
,
getDictOptions
}
from
'@/utils/dict'
import
{
FormInstance
,
UploadInstance
}
from
'element-plus'
// 业务相关的 import
import
{
getAccessToken
,
getTenantId
}
from
'@/utils/auth'
import
*
as
FormApi
from
'@/api/bpm/form'
<
script
setup
lang=
"ts"
name=
"Form"
>
import
{
DICT_TYPE
,
getIntDictOptions
}
from
'@/utils/dict'
import
{
dateFormatter
,
formatDate
}
from
'@/utils/formatTime'
import
*
as
ModelApi
from
'@/api/bpm/model'
import
{
allSchemas
,
rules
}
from
'./model.data'
import
{
setConfAndFields2
}
from
'@/utils/formCreate'
const
{
t
}
=
useI18n
()
// 国际化
const
message
=
useMessage
()
// 消息弹窗
const
router
=
useRouter
()
// 路由
const
showBpmnOpen
=
ref
(
false
)
const
bpmnXML
=
ref
(
null
)
const
bpmnControlForm
=
ref
({
prefix
:
'flowable'
import
ModelForm
from
'./ModelForm.vue'
// import { setConfAndFields2 } from '@/utils/formCreate'
// const message = useMessage() // 消息弹窗
// const { t } = useI18n() // 国际化
// const { push } = useRouter() // 路由
const
loading
=
ref
(
true
)
// 列表的加载中
const
total
=
ref
(
0
)
// 列表的总页数
const
list
=
ref
([])
// 列表的数据
const
queryParams
=
reactive
({
pageNo
:
1
,
pageSize
:
10
,
key
:
undefined
,
name
:
undefined
,
category
:
undefined
})
// ========== 列表相关 ==========
const
[
registerTable
,
{
reload
}]
=
useXTable
({
allSchemas
:
allSchemas
,
getListApi
:
ModelApi
.
getModelPageApi
})
const
forms
=
ref
()
// 流程表单的下拉框的数据
// 设计流程
const
handleDesign
=
(
row
)
=>
{
console
.
log
(
row
,
'设计流程'
)
router
.
push
({
name
:
'modelEditor'
,
query
:
{
modelId
:
row
.
id
}
})
}
// 跳转到指定流程定义列表
const
handleDefinitionList
=
(
row
)
=>
{
router
.
push
({
name
:
'BpmProcessDefinitionList'
,
query
:
{
key
:
row
.
key
}
})
}
// 流程表单的详情按钮操作
const
formDetailVisible
=
ref
(
false
)
const
formDetailPreview
=
ref
({
rule
:
[],
option
:
{}
})
const
handleFormDetail
=
async
(
row
)
=>
{
if
(
row
.
formType
==
10
)
{
// 设置表单
const
data
=
await
FormApi
.
getForm
(
row
.
formId
)
setConfAndFields2
(
formDetailPreview
,
data
.
conf
,
data
.
fields
)
// 弹窗打开
formDetailVisible
.
value
=
true
}
else
{
await
router
.
push
({
path
:
row
.
formCustomCreatePath
})
}
}
const
queryFormRef
=
ref
()
// 搜索的表单
// 流程图的详情按钮操作
const
handleBpmnDetail
=
(
row
)
=>
{
// TODO 芋艿:流程组件开发中
console
.
log
(
row
)
ModelApi
.
getModel
(
row
).
then
((
response
)
=>
{
console
.
log
(
response
,
'response'
)
bpmnXML
.
value
=
response
.
bpmnXml
// 弹窗打开
showBpmnOpen
.
value
=
true
})
// message.success('流程组件开发中,预计 2 月底完成')
}
// 点击任务分配按钮
const
handleAssignRule
=
(
row
)
=>
{
router
.
push
({
name
:
'BpmTaskAssignRuleList'
,
query
:
{
modelId
:
row
.
id
}
})
}
// ========== 新建/修改流程 ==========
const
dialogVisible
=
ref
(
false
)
const
dialogTitle
=
ref
(
'新建模型'
)
const
dialogLoading
=
ref
(
false
)
const
saveForm
=
ref
()
const
saveFormRef
=
ref
<
FormInstance
>
()
// 设置标题
const
setDialogTile
=
async
(
type
:
string
)
=>
{
dialogTitle
.
value
=
t
(
'action.'
+
type
)
dialogVisible
.
value
=
true
}
// 新增操作
const
handleCreate
=
async
()
=>
{
resetForm
()
await
setDialogTile
(
'create'
)
}
// 修改操作
const
handleUpdate
=
async
(
rowId
:
number
)
=>
{
resetForm
()
await
setDialogTile
(
'edit'
)
// 设置数据
saveForm
.
value
=
await
ModelApi
.
getModel
(
rowId
)
if
(
saveForm
.
value
.
category
==
null
)
{
saveForm
.
value
.
category
=
1
}
else
{
saveForm
.
value
.
category
=
Number
(
saveForm
.
value
.
category
)
}
}
// 提交按钮
const
submitForm
=
async
()
=>
{
// 参数校验
const
elForm
=
unref
(
saveFormRef
)
if
(
!
elForm
)
return
const
valid
=
await
elForm
.
validate
()
if
(
!
valid
)
return
// 提交请求
dialogLoading
.
value
=
true
/** 查询参数列表 */
const
getList
=
async
()
=>
{
loading
.
value
=
true
try
{
const
data
=
saveForm
.
value
as
ModelApi
.
ModelVO
if
(
!
data
.
id
)
{
await
ModelApi
.
createModelApi
(
data
)
message
.
success
(
t
(
'common.createSuccess'
))
}
else
{
await
ModelApi
.
updateModelApi
(
data
)
message
.
success
(
t
(
'common.updateSuccess'
))
}
dialogVisible
.
value
=
false
const
data
=
await
ModelApi
.
getModelPage
(
queryParams
)
list
.
value
=
data
.
list
total
.
value
=
data
.
total
}
finally
{
// 刷新列表
await
reload
()
dialogLoading
.
value
=
false
loading
.
value
=
false
}
}
// 重置表单
const
resetForm
=
()
=>
{
saveForm
.
value
=
{
formType
:
10
,
name
:
''
,
courseSort
:
''
,
description
:
''
,
formId
:
''
,
formCustomCreatePath
:
''
,
formCustomViewPath
:
''
}
saveFormRef
.
value
?.
resetFields
()
}
// ========== 删除 / 更新状态 / 发布流程 ==========
// 删除流程
const
handleDelete
=
(
rowId
)
=>
{
message
.
delConfirm
(
'是否删除该流程!!'
).
then
(
async
()
=>
{
await
ModelApi
.
deleteModelApi
(
rowId
)
message
.
success
(
t
(
'common.delSuccess'
))
// 刷新列表
reload
()
})
/** 搜索按钮操作 */
const
handleQuery
=
()
=>
{
queryParams
.
pageNo
=
1
getList
()
}
// 更新状态操作
const
handleChangeState
=
(
row
)
=>
{
const
id
=
row
.
id
const
state
=
row
.
processDefinition
.
suspensionState
const
statusState
=
state
===
1
?
'激活'
:
'挂起'
const
content
=
'是否确认'
+
statusState
+
'流程名字为"'
+
row
.
name
+
'"的数据项?'
message
.
confirm
(
content
)
.
then
(
async
()
=>
{
await
ModelApi
.
updateModelStateApi
(
id
,
state
)
message
.
success
(
t
(
'部署成功'
))
// 刷新列表
reload
()
})
.
catch
(()
=>
{
// 取消后,进行恢复按钮
row
.
processDefinition
.
suspensionState
=
state
===
1
?
2
:
1
})
/** 重置按钮操作 */
const
resetQuery
=
()
=>
{
queryFormRef
.
value
.
resetFields
()
handleQuery
()
}
// 发布流程
const
handleDeploy
=
(
row
)
=>
{
message
.
confirm
(
'是否部署该流程!!'
).
then
(
async
()
=>
{
await
ModelApi
.
deployModelApi
(
row
.
id
)
message
.
success
(
t
(
'部署成功'
))
// 刷新列表
reload
()
})
/** 添加/修改操作 */
const
formRef
=
ref
()
const
openForm
=
(
type
:
string
,
id
?:
number
)
=>
{
formRef
.
value
.
open
(
type
,
id
)
}
// ========== 导入流程 ==========
const
uploadRef
=
ref
<
UploadInstance
>
()
let
importUrl
=
import
.
meta
.
env
.
VITE_BASE_URL
+
import
.
meta
.
env
.
VITE_API_URL
+
'/bpm/model/import'
const
uploadHeaders
=
ref
()
const
importDialogVisible
=
ref
(
false
)
const
uploadDisabled
=
ref
(
false
)
const
importFormRef
=
ref
<
FormInstance
>
()
const
importForm
=
ref
({
key
:
''
,
name
:
''
,
description
:
''
})
// 导入流程弹窗显示
const
handleImport
=
()
=>
{
importDialogVisible
.
value
=
true
}
// 文件数超出提示
const
handleExceed
=
():
void
=>
{
message
.
error
(
'最多只能上传一个文件!'
)
}
// 上传错误提示
const
excelUploadError
=
():
void
=>
{
message
.
error
(
'导入流程失败,请您重新上传!'
)
}
// 提交文件上传
const
submitFileForm
=
()
=>
{
uploadHeaders
.
value
=
{
Authorization
:
'Bearer '
+
getAccessToken
(),
'tenant-id'
:
getTenantId
()
}
uploadDisabled
.
value
=
true
uploadRef
.
value
!
.
submit
()
}
// 文件上传成功
const
handleFileSuccess
=
async
(
response
:
any
):
Promise
<
void
>
=>
{
if
(
response
.
code
!==
0
)
{
message
.
error
(
response
.
msg
)
return
}
// 重置表单
uploadClose
()
// 提示,并刷新
message
.
success
(
'导入流程成功!请点击【设计流程】按钮,进行编辑保存后,才可以进行【发布流程】'
)
await
reload
()
}
// 关闭文件上传
const
uploadClose
=
()
=>
{
// 关闭弹窗
importDialogVisible
.
value
=
false
// 重置上传状态和文件
uploadDisabled
.
value
=
false
uploadRef
.
value
!
.
clearFiles
()
// 重置表单
importForm
.
value
=
{
key
:
''
,
name
:
''
,
description
:
''
}
importFormRef
.
value
?.
resetFields
()
}
/** 删除按钮操作 */
// const handleDelete = async (id: number) => {
// try {
// // 删除的二次确认
// await message.delConfirm()
// // 发起删除
// await FormApi.deleteForm(id)
// message.success(t('common.delSuccess'))
// // 刷新列表
// await getList()
// } catch {}
// }
/
/ ========== 初始化 ==========
/
** 初始化 **/
onMounted
(()
=>
{
// 获得流程表单的下拉框的数据
FormApi
.
getSimpleFormList
().
then
((
data
)
=>
{
forms
.
value
=
data
})
getList
()
})
</
script
>
src/views/bpm/model/model.data.ts
deleted
100644 → 0
View file @
d0ed5edb
import
type
{
VxeCrudSchema
}
from
'@/hooks/web/useVxeCrudSchemas'
const
{
t
}
=
useI18n
()
// 国际化
// 表单校验
export
const
rules
=
reactive
({
key
:
[
required
],
name
:
[
required
],
category
:
[
required
],
formType
:
[
required
],
formId
:
[
required
],
formCustomCreatePath
:
[
required
],
formCustomViewPath
:
[
required
]
})
// CrudSchema
const
crudSchemas
=
reactive
<
VxeCrudSchema
>
({
primaryKey
:
'key'
,
primaryType
:
null
,
action
:
true
,
actionWidth
:
'540px'
,
columns
:
[
{
title
:
'流程标识'
,
field
:
'key'
,
isSearch
:
true
,
table
:
{
width
:
120
}
},
{
title
:
'流程名称'
,
field
:
'name'
,
isSearch
:
true
,
table
:
{
width
:
120
,
slots
:
{
default
:
'name_default'
}
}
},
{
title
:
'流程分类'
,
field
:
'category'
,
dictType
:
DICT_TYPE
.
BPM_MODEL_CATEGORY
,
dictClass
:
'number'
,
isSearch
:
true
,
table
:
{
slots
:
{
default
:
'category_default'
}
}
},
{
title
:
'表单信息'
,
field
:
'formId'
,
table
:
{
width
:
180
,
slots
:
{
default
:
'formId_default'
}
}
},
{
title
:
'最新部署的流程定义'
,
field
:
'processDefinition'
,
isForm
:
false
,
table
:
{
children
:
[
{
title
:
'流程版本'
,
field
:
'version'
,
slots
:
{
default
:
'version_default'
},
width
:
80
},
{
title
:
'激活状态'
,
field
:
'status'
,
slots
:
{
default
:
'status_default'
},
width
:
80
},
{
title
:
'部署时间'
,
field
:
'processDefinition.deploymentTime'
,
formatter
:
'formatDate'
,
width
:
180
}
]
}
},
{
title
:
t
(
'common.createTime'
),
field
:
'createTime'
,
isForm
:
false
,
formatter
:
'formatDate'
,
table
:
{
width
:
180
}
}
]
})
export
const
{
allSchemas
}
=
useVxeCrudSchemas
(
crudSchemas
)
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