main
滕嵩 2024-03-26 09:08:15 +08:00
parent 489b8f22ed
commit d93b70f1d7
5 changed files with 453 additions and 0 deletions

View File

@ -0,0 +1,103 @@
<!--
* @Description: 渲染组件无法使用Vben的组件
-->
<template>
<Modal
title="新增数据"
:open="visible"
@ok="handleGetData"
@cancel="handleCancel"
:destroyOnClose="true"
:width="900"
>
<VFormCreate
:form-config="formConfig as any"
v-model:fApi="fApi"
v-model:formModel="formModel"
@submit="onSubmit"
>
<template #slotName="{ formModel, field }">
<a-input v-model:value="formModel[field]" placeholder="我是插槽传递的输入框" />
</template>
</VFormCreate>
<JsonModal ref="jsonModal" />
</Modal>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from 'vue';
import { IFormConfig } from '../../typings/v-form-component';
import { IAnyObject } from '../../typings/base-type';
import VFormCreate from '../VFormCreate/index.vue';
import { formatRules } from '../../utils';
import { IVFormMethods } from '../../hooks/useVFormMethods';
import JsonModal from '../VFormDesign/components/JsonModal.vue';
import { IToolbarMethods } from '../../typings/form-type';
import { Modal } from 'ant-design-vue';
export default defineComponent({
name: 'VFormPreview',
components: {
JsonModal,
VFormCreate,
Modal,
},
emits: ['renderdata'],
setup(props, { emit }) {
const jsonModal = ref<IToolbarMethods | null>(null);
const state = reactive<{
formModel: IAnyObject;
visible: boolean;
formConfig: IFormConfig;
fApi: IVFormMethods;
}>({
formModel: {},
formConfig: {} as IFormConfig,
visible: false,
fApi: {} as IVFormMethods,
});
/**
* 显示Json数据弹框
* @param jsonData
*/
const showModal = (jsonData: IFormConfig) => {
// console.log('showModal-', jsonData);
formatRules(jsonData.schemas);
state.formConfig = jsonData as any;
state.visible = true;
};
/**
* 获取表单数据
* @return {Promise<void>}
*/
const handleCancel = () => {
state.visible = false;
state.formModel = {};
};
const handleGetData = async () => {
const _data = await state.fApi.submit?.();
console.log('_data',_data)
emit('renderdata', _data);
//jsonModal.value?.showModal?.(_data)
};
const onSubmit = (_data: IAnyObject) => {
//
};
const onCancel = () => {
state.formModel = {};
};
return {
handleGetData,
handleCancel,
...toRefs(state),
showModal,
jsonModal,
onSubmit,
onCancel,
};
},
});
</script>

View File

@ -0,0 +1,71 @@
<!--
* @Description: 使用vbenForm的功能进行渲染
-->
<template>
<Modal
title="预览(不支持布局)"
:open="state.visible"
@ok="handleGetData"
@cancel="handleCancel"
okText="获取数据"
cancelText="关闭"
style="top: 20px"
:destroyOnClose="true"
:width="900"
>
<BasicForm v-bind="attrs" @register="registerForm" />
<JsonModal ref="jsonModal" />
</Modal>
</template>
<script lang="ts" setup>
import { BasicForm, useForm } from '@/components/Form';
import { reactive, ref, computed } from 'vue';
import { IFormConfig } from '../../typings/v-form-component';
import { IAnyObject } from '../../typings/base-type';
import JsonModal from '../VFormDesign/components/JsonModal.vue';
import { IToolbarMethods } from '../../typings/form-type';
import { Modal } from 'ant-design-vue';
const jsonModal = ref<IToolbarMethods | null>(null);
const state = reactive<{
formModel: IAnyObject;
visible: boolean;
formConfig: IFormConfig;
}>({
formModel: {},
formConfig: {} as IFormConfig,
visible: false,
});
const attrs = computed(() => {
return {
...state.formConfig,
} as Recordable;
});
/**
* 显示Json数据弹框
* @param jsonData
*/
const showModal = (jsonData: IFormConfig) => {
state.formConfig = jsonData as any;
state.visible = true;
};
//
const [registerForm, { validate }] = useForm();
const handleCancel = () => {
state.visible = false;
};
/**
* 获取表单数据
* @return {Promise<void>}
*/
const handleGetData = async () => {
let data = await validate();
jsonModal.value?.showModal?.(data);
};
defineExpose({ showModal });
</script>

View File

@ -0,0 +1,49 @@
import { BasicColumn, FormSchema } from '@/components/Table';
import { h } from 'vue';
import { Tag } from 'ant-design-vue';
export const columns: BasicColumn[] = [
{
title: '名称',
dataIndex: 'name',
},
{
title: '分类',
dataIndex: 'category',
},
{
title: '类型',
dataIndex: 'formType',
width: 80,
customRender: ({ record }) => {
const status = record.formType;
const enable = ~~status === 0;
const color = enable ? '#67c23a' : '#e6a23c';
const text = enable ? '常规表单' : '视图表单';
return h(Tag, { color: color }, () => text);
},
},
{
title: '创建人',
dataIndex: 'createUserName'
},
{
title: '创建时间',
dataIndex: 'createDate'
},
// {
// title: '备注',
// dataIndex: 'remark',
// },
];
export const searchFormSchema: FormSchema[] = [
{
field: 'key',
label: '关键字',
component: 'Input',
colProps: { span: 8 },
},
];

View File

@ -0,0 +1,121 @@
<template>
<BasicTable @register="registerTable">
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'action'">
<TableAction :actions="[
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
color: 'error',
popConfirm: {
title: '是否删除该数据',
confirm: handleDelete.bind(null, record),
},
}
]" />
</template>
</template>
<template #toolbar>
<a-button type="primary" @click="handleAddForm(eFormPreview!)"> </a-button>
</template>
</BasicTable>
<VformRender ref="eFormPreview" :formConfig="formConfig" @renderdata="renderdata" />
</template>
<script lang="ts" setup>
import { onMounted, ref, nextTick, unref,reactive } from 'vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getFormGroupList,getBaseConfigList } from '@/api/formdesign/index';
import { columns, searchFormSchema } from './index.data';
import { cloneDeep } from 'lodash-es';
import VformRender from '../../form-design/components/VformRender/index.vue';
import { IFormConfig,IToolbarMethods } from '../../form-design/typings/v-form-component';
const eFormPreview = ref<null | IToolbarMethods>(null);
const [registerTable, { reload, getSelectRows }] = useTable({
title: '表单列表',
api: getFormGroupList,
rowKey: 'f_Id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
},
useSearchForm: true,
showTableSetting: true,
bordered: true,
beforeFetch: (data) => {
//
var temp = {
page: data.page,
limit: data.limit,
keyWord: data.key,
category: data.f_Category
};
return temp;
},
afterFetch: (data) => {
},
handleSearchInfoFn(info) {
return info;
},
actionColumn: {
width: 180,
title: '操作',
dataIndex: 'action',
// slots: { customRender: 'action' },
fixed: undefined,
},
});
const formConfig = ref<IFormConfig>({
//
schemas: [],
layout: 'horizontal',
labelLayout: 'flex',
labelWidth: 100,
labelCol: {},
wrapperCol: {},
currentItem: {
component: '',
componentProps: {},
},
activeKey: 1,
});
const handleAddForm = (Modal: IToolbarMethods) => {
console.log('formConfig',formConfig)
const config = cloneDeep(formConfig.value);
Modal?.showModal(config);
}
function handleEdit(record: Recordable) {
}
function handleDelete(record: Recordable) {
// openAccountModal(true, {
// record,
// });
}
function getPublicForm(){
getBaseConfigList({ id: "ed985a1e-b007-43d1-af14-be4e44018c8b" }).then((res: AreaRespVO[]) =>{
let obj = JSON.parse(res.scheme.scheme)
console.log('res',obj.formInfo)
formConfig.value.schemas = obj.formInfo.schemas
})
}
//
function renderdata(e){
console.log('renderdata',e)
}
onMounted(() => {
getPublicForm()
})
</script>

View File

@ -0,0 +1,109 @@
<template>
<PageWrapper :class="prefixCls">
<a-tabs v-model:activeKey="activeName">
<a-tab-pane key="form" tab="表单信息">
</a-tab-pane>
<a-tab-pane key="flow" tab="流程信息" force-render>
<div class="process-design" :style="'display: flex; height:' + designerData.height">
<process-viewer :key="`designer-${id}`" :xml="flowContent" :flowViewer="flowViewer"/>
</div>
</a-tab-pane>
</a-tabs>
</PageWrapper>
</template>
<script lang="ts" setup>
import { h, ref, provide, reactive, onMounted, defineProps, computed, defineEmits, onBeforeMount } from 'vue';
import ProcessViewer from '@/components/ProcessViewer/index.vue';
import { PageWrapper } from '@/components/Page';
import { SendOutlined, SaveOutlined, CloseCircleOutlined, ZoomInOutlined, RotateLeftOutlined, RotateRightOutlined, ClearOutlined } from '@ant-design/icons-vue';
import { getBPMN } from '@/api/sys/WFProcess'
import { getLoadMyUserList } from '@/api/sys/WFDelegate'
import { useRoute } from 'vue-router'
import { useMultipleTabStore } from '@/store/modules/multipleTab';
import { useRouter } from 'vue-router';
import { buildGUID } from '@/utils/uuid';
import { useMessage } from '/@/hooks/web/useMessage';
const { createConfirm, createMessage } = useMessage();
const prefixCls = 'preview-box'
const tabStore = useMultipleTabStore();
const router = useRouter();
const content = ref('')
const flowContent = ref('')
const flowViewer = ref({})
const route = useRoute()
const id = route.query.id
const designerOpen = ref(false)
const formRef = ref();
const labelCol = { span: 7 };
const wrapperCol = { span: 13 };
const designerData = reactive({
loading: false,
xmlString: '',
controlForm: {
prefix: 'flowable',
},
height: document.documentElement.clientHeight - 230.5 + "px;",
midVisible: false,
isCustmerTitle: false,
nodeUsers: [],
selectUsersVisible: false,
isDraft: false,
delegateUsers: []
})
const activeName = ref('flow')
async function getDetailInfo() {
let data = await getBPMN({ id: id })
flowContent.value = data.flowContent
flowViewer.value = data.flowViewer
// var result = {
// // xml
// flowContent: "",
// // id
// flowViewer: {
// // id
// finishedTaskSet: [],
// // 线id
// finishedSequenceFlowSet: [],
// // id
// unfinishedTaskSet: [],
// // id
// rejectedTaskSet: [],
// }
// //
// }
}
function closePreview() {
if (!id) {
tabStore.closeTabByKey('/dashboard/task_preview/detail', router);
} else {
// /dashboard/create_preview/add?id=1
tabStore.closeTabByKey('/dashboard/task_preview/detail?id=' + id, router);
}
}
onBeforeMount(() => {
getDetailInfo()
})
</script>
<style lang="less" scoped>
.preview-box {
background-color: @component-background;
.btn-box {
padding: 10px;
justify-content: flex-end;
display: flex;
}
}
.form-box {
width: 480px;
}
</style>