feat: bpm form init

pull/12/head
xingyu 2023-05-15 18:12:28 +08:00
parent e405733429
commit 61ff8119a6
12 changed files with 255 additions and 13 deletions

View File

@ -193,3 +193,53 @@ export const runCode = <T>(code: any): T => {
return code
}
}
/**
* https://github.com/xaboy/form-create-designer 封装的工具类
*/
// 编码表单 Conf
export const encodeConf = (designerRef: object) => {
// @ts-ignore
return JSON.stringify(designerRef.value.getOption())
}
// 编码表单 Fields
export const encodeFields = (designerRef: object) => {
// @ts-ignore
const rule = designerRef.value.getRule()
const fields: string[] = []
rule.forEach((item) => {
fields.push(JSON.stringify(item))
})
return fields
}
// 解码表单 Fields
export const decodeFields = (fields: string[]) => {
const rule: object[] = []
fields.forEach((item) => {
rule.push(JSON.parse(item))
})
return rule
}
// 设置表单的 Conf 和 Fields
export const setConfAndFields = (designerRef: object, conf: string, fields: string) => {
// @ts-ignore
designerRef.value.setOption(JSON.parse(conf))
// @ts-ignore
designerRef.value.setRule(decodeFields(fields))
}
// 设置表单的 Conf 和 Fields
export const setConfAndFields2 = (detailPreview: object, conf: string, fields: string, value?: object) => {
// @ts-ignore
detailPreview.value.option = JSON.parse(conf)
// @ts-ignore
detailPreview.value.rule = decodeFields(fields)
if (value) {
// @ts-ignore
detailPreview.value.value = value
}
}

View File

@ -149,6 +149,131 @@ export const PayRoute: AppRouteRecordRaw = {
]
}
export const BpmRoute: AppRouteRecordRaw = {
path: '/bpm',
component: LAYOUT,
name: 'bpm',
meta: {
title: '工作流',
hidden: true
},
children: [
{
path: '/manager/form/edit',
component: () => import('@/views/bpm/form/editor/index.vue'),
name: 'BpmFormEditor',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '设计流程表单',
activeMenu: '/bpm/manager/form'
}
},
{
path: '/manager/model/edit',
component: () => import('@/views/bpm/model/editor/index.vue'),
name: 'BpmModelEditor',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '设计流程',
activeMenu: '/bpm/manager/model'
}
},
{
path: '/manager/definition',
component: () => import('@/views/bpm/definition/index.vue'),
name: 'BpmProcessDefinition',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '流程定义',
activeMenu: '/bpm/manager/model'
}
},
{
path: '/manager/task-assign-rule',
component: () => import('@/views/bpm/taskAssignRule/index.vue'),
name: 'BpmTaskAssignRuleList',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '任务分配规则'
}
},
{
path: '/process-instance/create',
component: () => import('@/views/bpm/processInstance/create/index.vue'),
name: 'BpmProcessInstanceCreate',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '发起流程',
activeMenu: 'bpm/processInstance/create'
}
},
{
path: '/process-instance/detail',
component: () => import('@/views/bpm/processInstance/detail/index.vue'),
name: 'BpmProcessInstanceDetail',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '流程详情',
activeMenu: 'bpm/processInstance/detail'
}
},
{
path: '/bpm/oa/leave/create',
component: () => import('@/views/bpm/oa/leave/create.vue'),
name: 'OALeaveCreate',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '发起 OA 请假',
activeMenu: 'bpm/oa/leave'
}
},
{
path: '/process-instance/detail',
component: () => import('@/views/bpm/oa/leave/detail.vue'),
name: 'OALeaveDetail',
meta: {
canTo: true,
hidden: true,
noTagsView: false,
icon: 'ant-design:edit-outlined',
title: '查看 OA 请假',
activeMenu: 'bpm/oa/leave'
}
}
]
}
// Basic routing without permission
// 未经许可的基本路由
export const basicRoutes = [LoginRoute, RootRoute, ProfileRoute, CodegenRoute, JobLogRoute, PayRoute, REDIRECT_ROUTE, PAGE_NOT_FOUND_ROUTE]
export const basicRoutes = [
LoginRoute,
RootRoute,
ProfileRoute,
CodegenRoute,
JobLogRoute,
PayRoute,
BpmRoute,
REDIRECT_ROUTE,
PAGE_NOT_FOUND_ROUTE
]

View File

@ -0,0 +1,41 @@
<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="表单详情" @ok="handleSubmit">
<VFormCreate :form-config="formConfig" />
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { VFormCreate } from '@/components/FormDesign'
import { BasicModal, useModalInner } from '@/components/Modal'
import { getForm } from '@/api/bpm/form'
defineOptions({ name: 'BpmFormModal' })
const { t } = useI18n()
const { createMessage } = useMessage()
const emit = defineEmits(['success', 'register'])
const formConfig = ref({
schemas: [],
rule: [],
option: {}
})
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
setModalProps({ confirmLoading: false })
const res = await getForm(data.record.id)
formConfig.value.schemas = res.fields
formConfig.value.option = res.conf
})
async function handleSubmit() {
try {
closeModal()
emit('success')
createMessage.success(t('common.saveSuccessText'))
} finally {
setModalProps({ confirmLoading: false })
}
}
</script>

View File

@ -0,0 +1,8 @@
<template>
<div>
<VFormDesign />
</div>
</template>
<script lang="ts" setup>
import { VFormDesign } from '@/components/FormDesign'
</script>

View File

@ -2,7 +2,7 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" v-auth="['system:post:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
<a-button type="primary" v-auth="['bpm:form:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
</template>
@ -10,12 +10,13 @@
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:post:update', onClick: handleEdit.bind(null, record) },
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'bpm:form:update', onClick: openForm.bind(null, record) },
{ icon: IconEnum.VIEW, label: t('action.detail'), auth: 'bpm:form:query', onClick: openDetail.bind(null, record) },
{
icon: IconEnum.DELETE,
color: 'error',
label: t('action.delete'),
auth: 'system:post:delete',
auth: 'bpm:form:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',
@ -27,11 +28,15 @@
</template>
</template>
</BasicTable>
<BpmFormModal @register="registerModal" @success="reload()" />
</div>
</template>
<script lang="ts" setup>
import { useGo } from '@/hooks/web/usePage'
import { useI18n } from '@/hooks/web/useI18n'
import { useMessage } from '@/hooks/web/useMessage'
import { useModal } from '@/components/Modal'
import BpmFormModal from './FormModal.vue'
import { IconEnum } from '@/enums/appEnum'
import { BasicTable, useTable, TableAction } from '@/components/Table'
import { deleteForm, getFormPage } from '@/api/bpm/form'
@ -39,8 +44,10 @@ import { columns, searchFormSchema } from './form.data'
defineOptions({ name: 'BpmForm' })
const go = useGo()
const { t } = useI18n()
const { createMessage } = useMessage()
const [registerModal, { openModal }] = useModal()
const [registerTable, { reload }] = useTable({
title: '流程表单列表',
@ -50,7 +57,7 @@ const [registerTable, { reload }] = useTable({
useSearchForm: true,
showTableSetting: true,
actionColumn: {
width: 140,
width: 180,
title: t('common.action'),
dataIndex: 'action',
fixed: 'right'
@ -61,11 +68,17 @@ function handleCreate() {
// openModal(true, { isUpdate: false })
}
function handleEdit(record: Recordable) {
console.info(record)
function openForm(record: Recordable) {
if (typeof record.id === 'number') {
go({ name: 'BpmFormEditor', query: { id: record.id } })
}
// openModal(true, { record, isUpdate: true })
}
function openDetail(record: Recordable) {
openModal(true, { record })
}
async function handleDelete(record: Recordable) {
await deleteForm(record.id)
createMessage.success(t('common.delSuccessText'))

View File

@ -2,7 +2,7 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" v-auth="['system:post:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
<a-button type="primary" v-auth="['bpm:user-group:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
</template>
@ -10,12 +10,12 @@
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:post:update', onClick: handleEdit.bind(null, record) },
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'bpm:user-group:update', onClick: handleEdit.bind(null, record) },
{
icon: IconEnum.DELETE,
color: 'error',
label: t('action.delete'),
auth: 'system:post:delete',
auth: 'bpm:user-group:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',

View File

@ -0,0 +1 @@
<template>123</template>

View File

@ -2,7 +2,7 @@
<div>
<BasicTable @register="registerTable">
<template #toolbar>
<a-button type="primary" v-auth="['system:post:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
<a-button type="primary" v-auth="['bpm:model:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
{{ t('action.create') }}
</a-button>
</template>
@ -10,12 +10,12 @@
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'system:post:update', onClick: handleEdit.bind(null, record) },
{ icon: IconEnum.EDIT, label: t('action.edit'), auth: 'bpm:model:update', onClick: handleEdit.bind(null, record) },
{
icon: IconEnum.DELETE,
color: 'error',
label: t('action.delete'),
auth: 'system:post:delete',
auth: 'bpm:model:delete',
popConfirm: {
title: t('common.delMessage'),
placement: 'left',

View File

@ -0,0 +1 @@
<template>123</template>

View File

@ -0,0 +1 @@
<template>123</template>

View File

@ -0,0 +1 @@
<template>123</template>

View File

@ -0,0 +1 @@
<template>123</template>