【功能新增】工作流:BPM Model 增加 type 标记是 BPMN 设计器,还是 SIMPLE 钉钉设计器

pull/452/head
YunaiV 2024-08-26 18:38:24 +08:00
parent ce0f6edba6
commit 898593696c
6 changed files with 135 additions and 105 deletions

View File

@ -38,6 +38,10 @@ export const updateModel = async (data: ModelVO) => {
return await request.put({ url: '/bpm/model/update', data: data }) return await request.put({ url: '/bpm/model/update', data: data })
} }
export const updateModelBpmn = async (data: ModelVO) => {
return await request.put({ url: '/bpm/model/update-bpmn', data: data })
}
// 任务状态修改 // 任务状态修改
export const updateModelState = async (id: number, state: number) => { export const updateModelState = async (id: number, state: number) => {
const data = { const data = {

View File

@ -437,3 +437,15 @@ export const ErpBizType = {
SALE_OUT: 21, SALE_OUT: 21,
SALE_RETURN: 22 SALE_RETURN: 22
} }
// ========== BPM 模块 ==========
export const BpmModelType = {
BPMN: 10, // BPMN 设计器
SIMPLE: 20 // 简易设计器
}
export const BpmModelFormType = {
NORMAL: 10, // 流程表单
CUSTOM: 20 // 业务表单
}

View File

@ -143,6 +143,7 @@ export enum DICT_TYPE {
INFRA_OPERATE_TYPE = 'infra_operate_type', INFRA_OPERATE_TYPE = 'infra_operate_type',
// ========== BPM 模块 ========== // ========== BPM 模块 ==========
BPM_MODEL_TYPE = 'bpm_model_type',
BPM_MODEL_FORM_TYPE = 'bpm_model_form_type', BPM_MODEL_FORM_TYPE = 'bpm_model_form_type',
BPM_TASK_CANDIDATE_STRATEGY = 'bpm_task_candidate_strategy', BPM_TASK_CANDIDATE_STRATEGY = 'bpm_task_candidate_strategy',
BPM_PROCESS_INSTANCE_STATUS = 'bpm_process_instance_status', BPM_PROCESS_INSTANCE_STATUS = 'bpm_process_instance_status',

View File

@ -35,7 +35,7 @@
placeholder="请输入流程名称" placeholder="请输入流程名称"
/> />
</el-form-item> </el-form-item>
<el-form-item v-if="formData.id" label="流程分类" prop="category"> <el-form-item label="流程分类" prop="category">
<el-select <el-select
v-model="formData.category" v-model="formData.category"
clearable clearable
@ -50,73 +50,84 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item v-if="formData.id" label="流程图标" prop="icon"> <el-form-item label="流程图标" prop="icon">
<UploadImg v-model="formData.icon" :limit="1" height="128px" width="128px" /> <UploadImg v-model="formData.icon" :limit="1" height="64px" width="64px" />
</el-form-item> </el-form-item>
<el-form-item label="流程描述" prop="description"> <el-form-item label="流程描述" prop="description">
<el-input v-model="formData.description" clearable type="textarea" /> <el-input v-model="formData.description" clearable type="textarea" />
</el-form-item> </el-form-item>
<div v-if="formData.id"> <el-form-item label="流程类型" prop="type">
<el-form-item label="表单类型" prop="formType"> <el-radio-group v-model="formData.type">
<el-radio-group v-model="formData.formType"> <el-radio
<el-radio v-for="dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_TYPE)"
v-for="dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_FORM_TYPE)" :key="dict.value"
:key="dict.value" :label="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 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"
effect="light"
placement="top"
> >
<i class="el-icon-question" style="padding-left: 5px"></i> {{ dict.label }}
</el-tooltip> </el-radio>
</el-form-item> </el-radio-group>
<el-form-item </el-form-item>
v-if="formData.formType === 20" <el-form-item label="表单类型" prop="formType">
label="表单查看地址" <el-radio-group v-model="formData.formType">
prop="formCustomViewPath" <el-radio
> v-for="dict in getIntDictOptions(DICT_TYPE.BPM_MODEL_FORM_TYPE)"
<el-input :key="dict.value"
v-model="formData.formCustomViewPath" :label="dict.value"
placeholder="请输入表单查看的组件地址"
style="width: 330px"
/>
<el-tooltip
class="item"
content="自定义表单的查看组件地址,使用 Vue 的组件地址例如说bpm/oa/leave/detail"
effect="light"
placement="top"
> >
<i class="el-icon-question" style="padding-left: 5px"></i> {{ dict.label }}
</el-tooltip> </el-radio>
</el-form-item> </el-radio-group>
</div> </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"
>
<i class="el-icon-question" style="padding-left: 5px"></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"
content="自定义表单的查看组件地址,使用 Vue 的组件地址例如说bpm/oa/leave/detail.vue"
effect="light"
placement="top"
>
<i class="el-icon-question" style="padding-left: 5px"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="是否可见" prop="visible">
<el-radio-group v-model="formData.visible">
<el-radio
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key="dict.value as string"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button :disabled="formLoading" type="primary" @click="submitForm"> </el-button> <el-button :disabled="formLoading" type="primary" @click="submitForm"> </el-button>
@ -125,11 +136,12 @@
</Dialog> </Dialog>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getBoolDictOptions, getIntDictOptions } from '@/utils/dict'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
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 { CategoryApi } from '@/api/bpm/category' import { CategoryApi } from '@/api/bpm/category'
import { BpmModelFormType, BpmModelType } from '@/utils/constants'
defineOptions({ name: 'ModelForm' }) defineOptions({ name: 'ModelForm' })
@ -141,21 +153,27 @@ const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 12 const formLoading = ref(false) // 12
const formType = ref('') // create - update - const formType = ref('') // create - update -
const formData = ref({ const formData = ref({
formType: 10,
name: '', name: '',
category: undefined, category: undefined,
icon: undefined, icon: undefined,
description: '', description: '',
type: BpmModelType.BPMN,
formType: BpmModelFormType.NORMAL,
formId: '', formId: '',
formCustomCreatePath: '', formCustomCreatePath: '',
formCustomViewPath: '' formCustomViewPath: '',
visible: true
}) })
const formRules = reactive({ const formRules = reactive({
name: [{ required: true, message: '参数名称不能为空', trigger: 'blur' }], name: [{ required: true, message: '流程名称不能为空', trigger: 'blur' }],
key: [{ required: true, message: '参数键名不能为空', trigger: 'blur' }], key: [{ required: true, message: '流程标识不能为空', trigger: 'blur' }],
category: [{ required: true, message: '参数分类不能为空', trigger: 'blur' }], category: [{ required: true, message: '流程分类不能为空', trigger: 'blur' }],
icon: [{ required: true, message: '参数图标不能为空', trigger: 'blur' }], icon: [{ required: true, message: '流程图标不能为空', trigger: 'blur' }],
value: [{ 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' }] visible: [{ required: true, message: '是否可见不能为空', trigger: 'blur' }]
}) })
const formRef = ref() // Ref const formRef = ref() // Ref
@ -225,14 +243,16 @@ const submitForm = async () => {
/** 重置表单 */ /** 重置表单 */
const resetForm = () => { const resetForm = () => {
formData.value = { formData.value = {
formType: 10,
name: '', name: '',
category: undefined, category: undefined,
icon: '', icon: undefined,
description: '', description: '',
type: BpmModelType.BPMN,
formType: BpmModelFormType.NORMAL,
formId: '', formId: '',
formCustomCreatePath: '', formCustomCreatePath: '',
formCustomViewPath: '' formCustomViewPath: '',
visible: true
} }
formRef.value?.resetFields() formRef.value?.resetFields()
} }

View File

@ -58,17 +58,17 @@ const initModeler = (item) => {
} }
/** 添加/修改模型 */ /** 添加/修改模型 */
const save = async (bpmnXml) => { const save = async (bpmnXml: string) => {
const data = { const data = {
...model.value, ...model.value,
bpmnXml: bpmnXml // bpmnXml bpmnXml: bpmnXml // bpmnXml
} as unknown as ModelApi.ModelVO } as unknown as ModelApi.ModelVO
// //
if (data.id) { if (data.id) {
await ModelApi.updateModel(data) await ModelApi.updateModelBpmn(data)
message.success('修改成功') message.success('修改成功')
} else { } else {
await ModelApi.createModel(data) await ModelApi.updateModelBpmn(data)
message.success('新增成功') message.success('新增成功')
} }
// //

View File

@ -58,7 +58,7 @@
@click="openForm('create')" @click="openForm('create')"
v-hasPermi="['bpm:model:create']" v-hasPermi="['bpm:model:create']"
> >
<Icon icon="ep:plus" class="mr-5px" /> 新建流程 <Icon icon="ep:plus" class="mr-5px" /> 新建
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
@ -147,7 +147,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="240" fixed="right"> <el-table-column label="操作" align="center" width="250" fixed="right">
<template #default="scope"> <template #default="scope">
<el-button <el-button
link link
@ -155,7 +155,7 @@
@click="openForm('update', scope.row.id)" @click="openForm('update', scope.row.id)"
v-hasPermi="['bpm:model:update']" v-hasPermi="['bpm:model:update']"
> >
修改流程 修改
</el-button> </el-button>
<el-button <el-button
link link
@ -163,15 +163,7 @@
@click="handleDesign(scope.row)" @click="handleDesign(scope.row)"
v-hasPermi="['bpm:model:update']" v-hasPermi="['bpm:model:update']"
> >
设计流程 设计
</el-button>
<el-button
link
type="primary"
@click="handleSimpleDesign(scope.row)"
v-hasPermi="['bpm:model:update']"
>
仿钉钉设计流程
</el-button> </el-button>
<el-button <el-button
link link
@ -179,7 +171,7 @@
@click="handleDeploy(scope.row)" @click="handleDeploy(scope.row)"
v-hasPermi="['bpm:model:deploy']" v-hasPermi="['bpm:model:deploy']"
> >
发布流程 发布
</el-button> </el-button>
<el-button <el-button
link link
@ -187,7 +179,7 @@
v-hasPermi="['bpm:process-definition:query']" v-hasPermi="['bpm:process-definition:query']"
@click="handleDefinitionList(scope.row)" @click="handleDefinitionList(scope.row)"
> >
流程定义 历史
</el-button> </el-button>
<el-button <el-button
link link
@ -237,6 +229,7 @@ import * as FormApi from '@/api/bpm/form'
import ModelForm from './ModelForm.vue' import ModelForm from './ModelForm.vue'
import { setConfAndFields2 } from '@/utils/formCreate' import { setConfAndFields2 } from '@/utils/formCreate'
import { CategoryApi } from '@/api/bpm/category' import { CategoryApi } from '@/api/bpm/category'
import { BpmModelType } from '@/utils/constants'
defineOptions({ name: 'BpmModel' }) defineOptions({ name: 'BpmModel' })
@ -321,21 +314,21 @@ const handleChangeState = async (row) => {
/** 设计流程 */ /** 设计流程 */
const handleDesign = (row) => { const handleDesign = (row) => {
push({ if (row.type == BpmModelType.BPMN) {
name: 'BpmModelEditor', push({
query: { name: 'BpmModelEditor',
modelId: row.id query: {
} modelId: row.id
}) }
} })
} else {
const handleSimpleDesign = (row) => { push({
push({ name: 'SimpleWorkflowDesignEditor',
name: 'SimpleWorkflowDesignEditor', query: {
query: { modelId: row.id
modelId: row.id }
} })
}) }
} }
/** 发布流程 */ /** 发布流程 */