---初始化后台管理web页面项目
This commit is contained in:
589
src/views/form/design/components/BasicConfigStep.vue
Normal file
589
src/views/form/design/components/BasicConfigStep.vue
Normal file
@ -0,0 +1,589 @@
|
||||
<template>
|
||||
<div class="step1">
|
||||
<div class="step1-form">
|
||||
<BasicForm @register="register" />
|
||||
</div>
|
||||
<template v-if="designType === 'data'">
|
||||
<Divider />
|
||||
<p>{{ t('添加数据库表(请先选择数据库-第一个选择的为主库)') }}</p>
|
||||
<div>
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="generatorConfig?.tableConfigs"
|
||||
:pagination="false"
|
||||
>
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.key === 'order'">
|
||||
<span>
|
||||
{{ index + 1 }}
|
||||
</span>
|
||||
</template>
|
||||
<template v-if="column.key === 'isMain'">
|
||||
<span>
|
||||
<a-tag :color="record.isMain ? 'blue' : 'orange'">
|
||||
{{ record.isMain ? t('主表') : t('附表') }}
|
||||
</a-tag>
|
||||
</span>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'relationField'">
|
||||
<template v-if="index > 0">
|
||||
<Select
|
||||
style="width: 200px"
|
||||
v-model:value="record[column.key]"
|
||||
:placeholder="t('请选择附表关联主表字段')"
|
||||
>
|
||||
<SelectOption
|
||||
v-for="(name, idx) in selectOptions[record.tableName]"
|
||||
:key="idx"
|
||||
:value="name"
|
||||
>
|
||||
{{ name }}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'relationTableField'">
|
||||
<template v-if="index > 0">
|
||||
<Select
|
||||
style="width: 200px"
|
||||
v-model:value="record[column.key]"
|
||||
:placeholder="t('请选择主表字段')"
|
||||
>
|
||||
<SelectOption
|
||||
v-for="(name, idx) in selectOptions[mainTable]"
|
||||
:key="idx"
|
||||
:value="name"
|
||||
>
|
||||
{{ name }}
|
||||
</SelectOption>
|
||||
</Select>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<DeleteTwoTone two-tone-color="#ff8080" @click="remove(index)" />
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-button type="dashed" block @click="add">
|
||||
<PlusOutlined />
|
||||
{{ t('新增') }}
|
||||
</a-button>
|
||||
</div>
|
||||
<SelectDatabase @register="registerModal" @success="handleSelectSuccess" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, inject, Ref, ref, toRaw, watch } from 'vue';
|
||||
import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
|
||||
import { getDatabaselinkMultiTableColumns } from '/@/api/system/databaselink';
|
||||
import { getAuthList } from '/@/api/system/authorize';
|
||||
import { Divider } from 'ant-design-vue';
|
||||
import { PlusOutlined, DeleteTwoTone } from '@ant-design/icons-vue';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import { SelectDatabase } from '/@/components/CreateCodeStep';
|
||||
import { Select } from 'ant-design-vue';
|
||||
import { debounce, uniqBy } from 'lodash-es';
|
||||
import { TableConfig } from '/@/model/generator/tableConfig';
|
||||
import { CustomFormConfig, GeneratorConfig } from '/@/model/generator/generatorConfig';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { TableInfo, FieldInfo, upperFieldDb } from '/@/components/Designer';
|
||||
import { JavaTypeConvertTsType } from '/@/utils/helper/designHelper';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const SelectOption = Select.Option;
|
||||
|
||||
const { notification } = useMessage();
|
||||
|
||||
const dataAuthPlaceholder = computed(() => {
|
||||
return generatorConfig!.isDataAuth ? t('请选择已有通用数据权限') : t('请先启用数据权限');
|
||||
});
|
||||
const dataAuthHelpMessage = `
|
||||
1.启用数据权限会判断主表是否包含RuleUserlD字段如果存在,则不进行表结构修改,如果不存在,则会对主表进行字段添加。
|
||||
2.RuleUserlD主要用来控制每一条记录的权限所属人新增时,默认将当前登录认作为权限所属人。
|
||||
3.在表单设计中会添加“批量设置权限所属人”功能启用后,拥有该按钮权限的人员可以设置每一条记录的权限所属人。
|
||||
`;
|
||||
const formSchemaData: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
label: t('表单名称'),
|
||||
required: true,
|
||||
component: 'Input',
|
||||
colProps: {
|
||||
span: 12,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: t('请输入表单名称'),
|
||||
onChange: debounce((val: ChangeEvent) => {
|
||||
customFormConfig!.name = val.target.value;
|
||||
}, 200),
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'category',
|
||||
label: t('表单分类'),
|
||||
component: 'DicSelect',
|
||||
required: true,
|
||||
componentProps: {
|
||||
placeholder: t('请选择表单分类'),
|
||||
itemId: '1419276800524424444',
|
||||
isShowAdd: false,
|
||||
onChange: debounce((id) => {
|
||||
customFormConfig!.category = id;
|
||||
}, 200),
|
||||
},
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
label: t('功能描述'),
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
placeholder: t('请输入功能描述'),
|
||||
onChange: debounce((val: ChangeEvent) => {
|
||||
customFormConfig!.remark = val.target.value;
|
||||
}, 200),
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'databaseId',
|
||||
label: t('数据库'),
|
||||
component: 'DbSelect',
|
||||
required: true,
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
placeholder: t('请选择数据库'),
|
||||
onChange: debounce((val, option) => {
|
||||
generatorConfig!.databaseId = val;
|
||||
if (option) isFieldUpper.value = upperFieldDb.includes(option.dbType);
|
||||
mainTableName.value = isFieldUpper.value
|
||||
? mainTableName.value.toUpperCase()
|
||||
: mainTableName.value;
|
||||
}, 200),
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'isDataAuth',
|
||||
label: t('数据权限'),
|
||||
component: 'Switch',
|
||||
required: false,
|
||||
colProps: { span: 12 },
|
||||
helpMessage: dataAuthHelpMessage,
|
||||
helpComponentProps: { maxWidth: '400px' },
|
||||
componentProps: {
|
||||
checkedValue: true,
|
||||
unCheckedValue: false,
|
||||
onChange: (val) => {
|
||||
if (!val) {
|
||||
setFieldsValue({ dataAuthList: [] });
|
||||
generatorConfig!.dataAuthList = [];
|
||||
}
|
||||
generatorConfig!.isDataAuth = val;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'dataAuthList',
|
||||
label: t('权限选择'),
|
||||
component: 'ApiSelect',
|
||||
required: false,
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
mode: 'multiple',
|
||||
placeholder: dataAuthPlaceholder,
|
||||
api: getAuthList,
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
getPopupContainer: () => document.body,
|
||||
onChange: (val) => {
|
||||
generatorConfig!.dataAuthList = val;
|
||||
},
|
||||
},
|
||||
dynamicDisabled: ({ values }) => {
|
||||
return !values.isDataAuth;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
label: t('表单名称'),
|
||||
required: true,
|
||||
component: 'Input',
|
||||
colProps: {
|
||||
span: 12,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: t('请输入表单名称'),
|
||||
onChange: debounce((val: ChangeEvent) => {
|
||||
customFormConfig!.name = val.target.value;
|
||||
}, 200),
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'category',
|
||||
label: t('表单分类'),
|
||||
component: 'DicSelect',
|
||||
required: true,
|
||||
componentProps: {
|
||||
placeholder: t('请选择表单分类'),
|
||||
itemId: '1419276800524424444',
|
||||
isShowAdd: false,
|
||||
onChange: debounce((id) => {
|
||||
customFormConfig!.category = id;
|
||||
}, 200),
|
||||
},
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
field: 'remark',
|
||||
label: t('功能描述'),
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
placeholder: t('请输入功能描述'),
|
||||
onChange: debounce((val: ChangeEvent) => {
|
||||
customFormConfig!.remark = val.target.value;
|
||||
}, 200),
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'isDataAuth',
|
||||
label: t('数据权限'),
|
||||
component: 'Switch',
|
||||
required: false,
|
||||
colProps: { span: 12 },
|
||||
helpMessage: dataAuthHelpMessage,
|
||||
helpComponentProps: { maxWidth: '400px' },
|
||||
componentProps: {
|
||||
checkedValue: true,
|
||||
unCheckedValue: false,
|
||||
onChange: (val) => {
|
||||
if (!val) {
|
||||
setFieldsValue({ dataAuthList: [] });
|
||||
generatorConfig!.dataAuthList = [];
|
||||
}
|
||||
generatorConfig!.isDataAuth = val;
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'dataAuthList',
|
||||
label: t('权限选择'),
|
||||
component: 'ApiSelect',
|
||||
required: false,
|
||||
colProps: { span: 12 },
|
||||
componentProps: {
|
||||
mode: 'multiple',
|
||||
placeholder: dataAuthPlaceholder,
|
||||
api: getAuthList,
|
||||
labelField: 'name',
|
||||
valueField: 'id',
|
||||
getPopupContainer: () => document.body,
|
||||
onChange: (val) => {
|
||||
generatorConfig!.dataAuthList = val;
|
||||
},
|
||||
},
|
||||
dynamicDisabled: ({ values }) => {
|
||||
return !values.isDataAuth;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: t('序号'),
|
||||
dataIndex: 'order',
|
||||
key: 'order',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: t('类别'),
|
||||
dataIndex: 'isMain',
|
||||
key: 'isMain',
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: t('表名'),
|
||||
dataIndex: 'tableName',
|
||||
key: 'tableName',
|
||||
},
|
||||
{
|
||||
title: t('关联字段'),
|
||||
dataIndex: 'relationField',
|
||||
key: 'relationField',
|
||||
},
|
||||
{
|
||||
title: t('关联表字段'),
|
||||
key: 'relationTableField',
|
||||
dataIndex: 'relationTableField',
|
||||
},
|
||||
{
|
||||
title: t('操作'),
|
||||
key: 'action',
|
||||
align: 'center',
|
||||
},
|
||||
];
|
||||
|
||||
const selectOptions = ref({});
|
||||
const selectTableName = computed(() =>
|
||||
generatorConfig!.tableConfigs!.map((item) => item.tableName),
|
||||
);
|
||||
|
||||
const mainTable = computed(
|
||||
() => generatorConfig!.tableConfigs!.find((item) => item.isMain)!.tableName,
|
||||
);
|
||||
|
||||
const generatorConfig = inject<GeneratorConfig>('generatorConfig');
|
||||
const customFormConfig = inject<CustomFormConfig>('customFormConfig');
|
||||
const tableInfo = inject<Ref<TableInfo[]>>('tableInfo');
|
||||
const designType = inject<string>('designType');
|
||||
const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
|
||||
let mainTableName = inject<Ref<string>>('mainTableName', ref(''));
|
||||
const formType = inject<Ref<number>>('formType');
|
||||
|
||||
watch(
|
||||
() => generatorConfig?.databaseId,
|
||||
(val, oldVal) => {
|
||||
const { tableConfigs } = generatorConfig!;
|
||||
if (
|
||||
designType === 'data' &&
|
||||
val &&
|
||||
val !== oldVal &&
|
||||
tableConfigs &&
|
||||
tableConfigs.length > 0
|
||||
) {
|
||||
getDatabaselinkColumns(val);
|
||||
}
|
||||
},
|
||||
);
|
||||
watch(
|
||||
() => generatorConfig?.formJson,
|
||||
(val) => {
|
||||
if (!val) return;
|
||||
if (val.list.length > 0 || val.hiddenComponent.length > 0) {
|
||||
updateSchema({
|
||||
field: 'databaseId',
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
updateSchema({
|
||||
field: 'databaseId',
|
||||
componentProps: {
|
||||
disabled: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
const filterFormSchema=(formSchema:FormSchema[])=>{
|
||||
customFormConfig.formType=formType.value;
|
||||
const rtSchema=[];
|
||||
for(let i=0;i<formSchema.length;i++){
|
||||
let item=formSchema[i];
|
||||
if(item.field=='category'){
|
||||
if(formType.value==1){
|
||||
rtSchema.push(item);
|
||||
}
|
||||
}else{
|
||||
rtSchema.push(item);
|
||||
}
|
||||
}
|
||||
return rtSchema;
|
||||
};
|
||||
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
|
||||
const [register, { validate, getFieldsValue, setFieldsValue, updateSchema }] = useForm({
|
||||
labelWidth: 100,
|
||||
schemas: designType === 'data' ? filterFormSchema(formSchemaData) : filterFormSchema(formSchema),
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
|
||||
const add = async () => {
|
||||
try {
|
||||
const values = await validate();
|
||||
openModal(true, { databaseId: values.databaseId, selectTableName: selectTableName.value });
|
||||
} catch (error) {}
|
||||
};
|
||||
|
||||
const handleSelectSuccess = (selectRows: TableConfig[]) => {
|
||||
if (generatorConfig?.tableConfigs && generatorConfig?.tableConfigs.length === 0) {
|
||||
generatorConfig!.tableConfigs = [...toRaw(selectRows)];
|
||||
} else {
|
||||
generatorConfig!.tableConfigs = uniqBy(
|
||||
generatorConfig!.tableConfigs!.concat([...selectRows]),
|
||||
'tableName',
|
||||
);
|
||||
}
|
||||
const formData = getFieldsValue();
|
||||
getDatabaselinkColumns(formData.databaseId);
|
||||
};
|
||||
|
||||
const remove = (index) => {
|
||||
// TODO 这里删除 可能会引起 表单设计步骤所有的设计 出错。3个解决方案
|
||||
//1 删除后提示用户 表单设计全部清空!
|
||||
//2 删除之后根据所删除的表名 去表单设计Json匹配 所绑定的组件 全部将绑定表置空!
|
||||
//3 表单设计后 不允许删除表配置!
|
||||
|
||||
//如果删除的数据是主表 并且还有其他表 默认顺序 找下一张表 将其设为主表
|
||||
if (generatorConfig!.tableConfigs![index].isMain && generatorConfig!.tableConfigs!.length > 1) {
|
||||
const nextObj = generatorConfig!.tableConfigs![index + 1];
|
||||
nextObj.isMain = true;
|
||||
nextObj.relationField = '';
|
||||
nextObj.relationTableField = '';
|
||||
|
||||
const nextTable = tableInfo!.value![index + 1];
|
||||
nextTable.isMain = true;
|
||||
|
||||
generatorConfig!.tableConfigs!.splice(index, 1);
|
||||
tableInfo?.value.splice(index, 1);
|
||||
} else {
|
||||
generatorConfig!.tableConfigs!.splice(index, 1);
|
||||
tableInfo?.value.splice(index, 1);
|
||||
}
|
||||
};
|
||||
const getDatabaselinkColumns = (databaseId) => {
|
||||
getDatabaselinkMultiTableColumns({
|
||||
id: databaseId,
|
||||
tableNames: selectTableName.value.join(','),
|
||||
}).then((result) => {
|
||||
for (const key in result) {
|
||||
const columnInfo = result[key];
|
||||
|
||||
//如果已经写入过的表格 不再添加
|
||||
if (!tableInfo?.value.find((x) => x.name === key)) {
|
||||
const fields = columnInfo.map((field) => {
|
||||
const filedInfo: FieldInfo = {
|
||||
name: field.column,
|
||||
length: field.dataLength,
|
||||
type: JavaTypeConvertTsType(field.dataType),
|
||||
isPk: field.primaryKey,
|
||||
isNullable: field.nullable,
|
||||
};
|
||||
return filedInfo;
|
||||
});
|
||||
|
||||
tableInfo?.value.push({
|
||||
name: key,
|
||||
isMain: generatorConfig!.tableConfigs!.find((x) => x.tableName === key)
|
||||
?.isMain as boolean,
|
||||
fields: fields,
|
||||
});
|
||||
|
||||
const thisTableConfig = generatorConfig!.tableConfigs!.find((x) => x.tableName === key);
|
||||
|
||||
const col = columnInfo.find((x) => x.primaryKey);
|
||||
thisTableConfig!.pkField = col.column;
|
||||
thisTableConfig!.pkType = col.dataType;
|
||||
}
|
||||
|
||||
selectOptions.value[key] = columnInfo.map((x) => x.column);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//验证当前步骤的数据
|
||||
const validateStep = async (): Promise<boolean> => {
|
||||
try {
|
||||
await validate();
|
||||
if (designType !== 'data') {
|
||||
return true;
|
||||
}
|
||||
const { tableConfigs } = generatorConfig as GeneratorConfig;
|
||||
|
||||
//判断tableconfig 是否为空 或者 一条数据都没有
|
||||
if (!tableConfigs || tableConfigs!.length === 0) {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: t('数据表配置不能为空!'),
|
||||
}); //提示消息
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const config of tableConfigs!) {
|
||||
//如果是主表 可以不需要关联字段等
|
||||
if (config.isMain) {
|
||||
if (!config.tableName) {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: t('主表表名未能配置成功!'),
|
||||
}); //提示消息
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
//子表需要验证关联字段 已经关联表 是否选择好
|
||||
if (!config.tableName) {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: t('子表表名未能配置成功!'),
|
||||
}); //提示消息
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!config.relationField) {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: t(`{name} 表 关联字段未选中`, { name: config.tableName }),
|
||||
}); //提示消息
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!config.relationTableField) {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: t(`{name} 表 关联表字段未选中`, { name: config.tableName }),
|
||||
}); //提示消息
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
defineExpose({ validateStep, setFieldsValue });
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.step1 {
|
||||
h3 {
|
||||
margin: 0 0 12px;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 0 0 4px;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
p {
|
||||
color: @text-color;
|
||||
}
|
||||
}
|
||||
|
||||
.pay-select {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.pay-input {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
:deep(.ant-table-tbody > tr > td) {
|
||||
padding: 16px 8px;
|
||||
}
|
||||
</style>
|
||||
298
src/views/form/design/components/CodeGeneratorModal.vue
Normal file
298
src/views/form/design/components/CodeGeneratorModal.vue
Normal file
@ -0,0 +1,298 @@
|
||||
<template>
|
||||
<BasicModal @register="registerModal" v-bind="$attrs" wrapClassName="form-modal">
|
||||
<template #title>
|
||||
<div class="step-form-form">
|
||||
<a href="https://fcdma.gdyditc.com/" target="_blank">
|
||||
<DesignLogo />
|
||||
</a>
|
||||
<span>•</span>
|
||||
<span>{{ t('表单生成代码配置') }}</span>
|
||||
<a-steps :current="current">
|
||||
<a-step :title="t('基本信息')" />
|
||||
<a-step :title="t('界面设计')" />
|
||||
<a-step :title="t('代码预览')" />
|
||||
<a-step :title="t('菜单设置')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<a-button type="primary" @click="handleStepPrev" v-show="current !== 0">{{
|
||||
t('上一步')
|
||||
}}</a-button>
|
||||
<a-button type="primary" @click="handleStepNext" v-show="current < 3">{{
|
||||
t('下一步')
|
||||
}}</a-button>
|
||||
<a-button type="primary" @click="handleSave" v-show="current === 3">{{
|
||||
t('保存')
|
||||
}}</a-button>
|
||||
<a-button type="primary" danger @click="handleClose">{{ t('关闭') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="step-container">
|
||||
<StructureConfigStep
|
||||
ref="structureConfigStepRef"
|
||||
v-show="current === 0"
|
||||
:isFormGenerator="true"
|
||||
/>
|
||||
<ViewDesignStep ref="viewDesignStepRef" v-show="current === 1" :isFormGenerator="true" />
|
||||
<PreviewCodeStep ref="previewCodeStepRef" v-show="current === 2" :isFormGenerator="true" />
|
||||
<MenuConfigStep ref="menuConfigStepRef" v-show="current === 3" />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, watch, Ref } from 'vue';
|
||||
import PreviewCodeStep from '/@/views/generator/dev/components/PreviewCodeStep.vue';
|
||||
import {
|
||||
StructureConfigStep,
|
||||
ViewDesignStep,
|
||||
MenuConfigStep,
|
||||
} from '/@/components/CreateCodeStep';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { GeneratorModel } from '/@/api/system/generator/model';
|
||||
import { FormProps } from '/@/components/Form';
|
||||
import { buildOption } from '/@/utils/helper/designHelper';
|
||||
import { buildCode } from '/@/utils/helper/generatorHelper';
|
||||
import { CustomFormConfig, GeneratorConfig } from '/@/model/generator/generatorConfig';
|
||||
import { TableInfo } from '/@/components/Designer';
|
||||
import { getFormTemplate } from '/@/api/form/design';
|
||||
import { dataFirstGeneratorCode } from '/@/api/system/generator';
|
||||
import { useUserStore } from '/@/store/modules/user';
|
||||
import { FormTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import * as antd from '/@/components/Designer/src/types';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
const { t } = useI18n();
|
||||
const userStore = useUserStore();
|
||||
const current = ref(0);
|
||||
|
||||
const structureConfigStepRef = ref();
|
||||
const viewDesignStepRef = ref();
|
||||
const previewCodeStepRef = ref();
|
||||
const menuConfigStepRef = ref();
|
||||
|
||||
const tableInfo = ref<TableInfo[]>([]);
|
||||
const widgetForm = JSON.parse(JSON.stringify(antd.widgetForm));
|
||||
|
||||
const emits = defineEmits(['success', 'register', 'close']);
|
||||
const isGetInfo = ref<boolean>(false);
|
||||
|
||||
// const templateInfo = inject('getTemplateInfo');
|
||||
|
||||
let generatorConfig = reactive<GeneratorConfig>({
|
||||
databaseId: '', //数据库id
|
||||
tableConfigs: [],
|
||||
tableStructureConfigs: [],
|
||||
formJson: {},
|
||||
formEventConfig: {},
|
||||
listConfig: {
|
||||
isLeftMenu: false,
|
||||
queryConfigs: [],
|
||||
leftMenuConfig: {
|
||||
datasourceType: 'static',
|
||||
listFieldName: undefined,
|
||||
apiConfig: {},
|
||||
dictionaryItemId: undefined,
|
||||
menuName: '',
|
||||
parentIcon: '',
|
||||
childIcon: '',
|
||||
staticData: [],
|
||||
},
|
||||
columnConfigs: [],
|
||||
buttonConfigs: [],
|
||||
defaultOrder: true,
|
||||
isPage: true,
|
||||
},
|
||||
menuConfig: {},
|
||||
outputConfig: {
|
||||
creator: userStore.getUserInfo.name,
|
||||
isMenu: true,
|
||||
},
|
||||
});
|
||||
let customFormConfig = reactive<CustomFormConfig>({
|
||||
name: '',
|
||||
category: '',
|
||||
formDesignType: 0,
|
||||
formType: FormTypeEnum.CUSTOM_FORM,
|
||||
formJson: generatorConfig,
|
||||
remark: '',
|
||||
});
|
||||
|
||||
provide<GeneratorConfig>('generatorConfig', generatorConfig);
|
||||
provide<CustomFormConfig>('customFormConfig', customFormConfig);
|
||||
provide<Ref<TableInfo[]>>('tableInfo', tableInfo);
|
||||
provide('widgetForm', widgetForm);
|
||||
provide<Ref<number>>('current', current); //当前步骤
|
||||
watch(
|
||||
() => generatorConfig,
|
||||
() => {
|
||||
console.log(generatorConfig, 'generatorConfig:>>watch');
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => customFormConfig,
|
||||
() => {
|
||||
console.log(customFormConfig, 'customFormConfig:>>watch');
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
defaultFullscreen: true,
|
||||
destroyOnClose: true,
|
||||
draggable: false,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
footer: null,
|
||||
closable: false,
|
||||
});
|
||||
const res = await getFormTemplate(data.formId);
|
||||
const formJson = JSON.parse(res.formJson);
|
||||
generatorConfig.databaseId = formJson.databaseId;
|
||||
generatorConfig.formJson = formJson.formJson;
|
||||
generatorConfig.tableConfigs = formJson.tableConfigs;
|
||||
generatorConfig.tableStructureConfigs = formJson.tableStructureConfigs;
|
||||
generatorConfig.formEventConfig = formJson.formEventConfig;
|
||||
generatorConfig.outputConfig.dataAuthList = formJson.dataAuthList;
|
||||
generatorConfig.outputConfig.type =res.formDesignType
|
||||
generatorConfig.outputConfig.isDataAuth = formJson.isDataAuth;
|
||||
isGetInfo.value = true;
|
||||
});
|
||||
|
||||
function handleClose() {
|
||||
closeModal();
|
||||
emits('close');
|
||||
}
|
||||
//上一步
|
||||
function handleStepPrev() {
|
||||
current.value--;
|
||||
}
|
||||
//下一步
|
||||
async function handleStepNext() {
|
||||
const isOk = await stepValidate[current.value]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
current.value++;
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
const isOk = await stepValidate[3]();
|
||||
if (
|
||||
generatorConfig.formJson?.hiddenComponent &&
|
||||
generatorConfig.formJson?.hiddenComponent.length
|
||||
) {
|
||||
generatorConfig.formJson.list.push(...generatorConfig.formJson.hiddenComponent);
|
||||
}
|
||||
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
const data = generatorConfig as GeneratorModel;
|
||||
data.frontCode = buildCode(
|
||||
generatorConfig,
|
||||
tableInfo.value,
|
||||
buildOption(generatorConfig.formJson) as FormProps,
|
||||
);
|
||||
await dataFirstGeneratorCode(data);
|
||||
closeModal();
|
||||
emits('success');
|
||||
emits('close');
|
||||
}
|
||||
|
||||
const stepValidate = {
|
||||
//数据表配置 验证
|
||||
0: () => structureConfigStepRef.value.validateStep(),
|
||||
1: () => viewDesignStepRef.value.validateStep(),
|
||||
2: () => previewCodeStepRef.value.validateStep(),
|
||||
3: () => menuConfigStepRef.value.validateStep(),
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@keyframes rotation {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationReverse {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-process) {
|
||||
.ant-steps-item-icon {
|
||||
border: 2px solid #fff;
|
||||
outline: 2px dashed #1890ff !important;
|
||||
line-height: 30px;
|
||||
animation: rotation 4s linear infinite;
|
||||
|
||||
.ant-steps-icon {
|
||||
display: inline-block;
|
||||
animation: rotationReverse 4s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-form-content {
|
||||
padding: 24px;
|
||||
background-color: @component-background;
|
||||
}
|
||||
|
||||
.step-form-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
|
||||
a {
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
margin: 0 20px 0 -5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.ant-steps) {
|
||||
width: calc(100% - 750px);
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-container) {
|
||||
padding: 2px 0 2px 2px;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.step1 {
|
||||
padding: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
112
src/views/form/design/components/DesignModal.vue
Normal file
112
src/views/form/design/components/DesignModal.vue
Normal file
@ -0,0 +1,112 @@
|
||||
// 自定义表单
|
||||
<template>
|
||||
<BasicModal @register="registerModal" v-bind="$attrs">
|
||||
<GroupCard :growCardList="items" />
|
||||
<DataFirstModal
|
||||
v-if="state.isShowDataFirst"
|
||||
@register="registerDataFirst"
|
||||
@success="handleSuccess"
|
||||
@close="handleClose('isShowDataFirst')"
|
||||
/>
|
||||
<CodeFirstModal
|
||||
v-if="state.isShowCodeFirst"
|
||||
@register="registerCodeFirst"
|
||||
@success="handleSuccess"
|
||||
@close="handleClose('isShowCodeFirst')"
|
||||
/>
|
||||
<SimpleTemplateModal
|
||||
v-if="state.isShowSimpleTemplate"
|
||||
@register="registerSimpleTemplate"
|
||||
@success="handleSuccess"
|
||||
@close="handleClose('isShowSimpleTemplate')"
|
||||
/>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive } from 'vue';
|
||||
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
|
||||
import GroupCard from '/@/views/generator/dev/components/GroupCard.vue';
|
||||
import DataFirstModal from './components/DataFirstModal.vue';
|
||||
import CodeFirstModal from './components/CodeFirstModal.vue';
|
||||
import SimpleTemplateModal from './components/SimpleTemplateModal.vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import interfaceFirstPng from '/@/assets/images/design/interfaceFirst.png';
|
||||
import dataFirst from '/@/assets/images/design/dataFirst.png';
|
||||
import simpleTemplate from '/@/assets/images/design/simpleTemplate.png';
|
||||
import quickDevelop from '/@/assets/images/design/quickDevelop.png';
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
const [registerDataFirst, { openModal: openDataFirstModal }] = useModal();
|
||||
const [registerCodeFirst, { openModal: openCodeFirstModal }] = useModal();
|
||||
const [registerSimpleTemplate, { openModal: openSimpleTemplateModal }] = useModal();
|
||||
|
||||
const emits = defineEmits(['success', 'register']);
|
||||
|
||||
const items = [
|
||||
{
|
||||
name: t('界面优先'),
|
||||
content: t('以界面为基础设计并生成单表或多表的基础功能'),
|
||||
btnName: t('设计功能'),
|
||||
image: interfaceFirstPng,
|
||||
func: () => {
|
||||
openCodeFirstModal(true, { undoAble: true });
|
||||
},
|
||||
},
|
||||
{
|
||||
name: t('数据优先'),
|
||||
content: t('以数据为基础设置生成单表或多表的基础功能'),
|
||||
btnName: t('设计功能'),
|
||||
image: dataFirst,
|
||||
func: () => {
|
||||
openDataFirstModal(true, { undoAble: true });
|
||||
},
|
||||
},
|
||||
{
|
||||
name: t('简易模板'),
|
||||
content: t('通过简单操作生成不需要考虑数据库的基础功能'),
|
||||
btnName: t('设计功能'),
|
||||
image: simpleTemplate,
|
||||
func: () => {
|
||||
openSimpleTemplateModal(true, { undoAble: true });
|
||||
},
|
||||
},
|
||||
{
|
||||
name: t('快速生成代码'),
|
||||
content: t('根据数据表结构自动快速生成功能代码'),
|
||||
btnName: t('设计功能'),
|
||||
image: quickDevelop,
|
||||
func: () => {
|
||||
router.push({ path: '/dataconfig/database' });
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
canFullscreen: false,
|
||||
defaultFullscreen: true,
|
||||
draggable: false,
|
||||
title: data.title,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
});
|
||||
});
|
||||
const state = reactive({
|
||||
isShowDataFirst: true,
|
||||
isShowCodeFirst: true,
|
||||
isShowSimpleTemplate: true,
|
||||
});
|
||||
const handleClose = (modal) => {
|
||||
state[modal] = !state[modal];
|
||||
setTimeout(() => {
|
||||
state[modal] = !state[modal];
|
||||
}, 100);
|
||||
};
|
||||
|
||||
const handleSuccess = () => {
|
||||
emits('success');
|
||||
closeModal();
|
||||
};
|
||||
</script>
|
||||
128
src/views/form/design/components/HistoryModal.vue
Normal file
128
src/views/form/design/components/HistoryModal.vue
Normal file
@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<BasicModal @register="registerCategoryModal" v-bind="$attrs">
|
||||
<BasicTable @register="registerTable">
|
||||
<template #action="{ record }">
|
||||
<a-button type="link" v-if="record.activityFlag === 1" @click="handlePreview(record.id)"
|
||||
>{{ t('预览') }}
|
||||
</a-button>
|
||||
<div v-else class="flex justify-around">
|
||||
<a-button type="link" @click="handlePreview(record.id)">{{ t('预览') }} </a-button>
|
||||
<a-popconfirm
|
||||
:title="t('确认要将当前表单更新到此历史版本吗?')"
|
||||
:ok-text="t('确定')"
|
||||
:cancel-text="t('取消')"
|
||||
@confirm="handleVersion(record)"
|
||||
>
|
||||
<a-button type="link">{{ t('更新到此版本') }} </a-button>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</BasicModal>
|
||||
<PreviewModal @register="registerPreviewModal" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicModal, useModal, useModalInner } from '/@/components/Modal';
|
||||
import PreviewModal from './PreviewModal.vue';
|
||||
import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
|
||||
import { getFormHistoryInfo, setFormHistoryVersion } from '/@/api/form/design';
|
||||
import { getFormHistory } from '/@/api/form/design';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
const { t } = useI18n();
|
||||
const columns: BasicColumn[] = [
|
||||
{
|
||||
dataIndex: 'activityFlag',
|
||||
title: t('状态'),
|
||||
customRender: ({ record }) =>
|
||||
`${record.activityFlag === 1 ? t('当前版本') : t('非当前版本')}`, //1-当前版本 0-非当前版本
|
||||
},
|
||||
{
|
||||
dataIndex: 'version',
|
||||
title: t('版本'),
|
||||
},
|
||||
|
||||
{
|
||||
dataIndex: 'createUserName',
|
||||
title: t('创建人'),
|
||||
},
|
||||
{
|
||||
dataIndex: 'createDate',
|
||||
title: t('创建时间'),
|
||||
},
|
||||
];
|
||||
|
||||
const formId = ref<string>('');
|
||||
const { notification } = useMessage();
|
||||
|
||||
const [registerPreviewModal, { openModal }] = useModal();
|
||||
|
||||
const [registerCategoryModal, { setModalProps }] = useModalInner(async (data) => {
|
||||
formId.value = data.formId;
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
draggable: false,
|
||||
title: data.title,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
destroyOnClose: true,
|
||||
width: 800,
|
||||
});
|
||||
});
|
||||
const [registerTable, { reload }] = useTable({
|
||||
api: getFormHistory,
|
||||
beforeFetch: () => {
|
||||
return formId.value;
|
||||
},
|
||||
rowKey: 'id',
|
||||
columns,
|
||||
showTableSetting: false,
|
||||
bordered: true,
|
||||
maxHeight: 200,
|
||||
actionColumn: {
|
||||
width: 180,
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
},
|
||||
});
|
||||
|
||||
const handlePreview = async (id) => {
|
||||
if (!id) {
|
||||
notification.warning({
|
||||
message: t('提示'),
|
||||
description: t('请先选择要预览的数据项'),
|
||||
}); //提示消息
|
||||
return;
|
||||
}
|
||||
const templateJson = await getFormHistoryInfo(id);
|
||||
openModal(true, { title: t('预览'), formJson: templateJson.formJson });
|
||||
};
|
||||
|
||||
const handleVersion = (data) => {
|
||||
setFormHistoryVersion({ formId: data.formId, id: data.id }).then((res) => {
|
||||
if (res) {
|
||||
notification.success({
|
||||
message: t('提示'),
|
||||
description: t('更新版本成功'),
|
||||
});
|
||||
reload();
|
||||
} else {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: t('更新版本失败'),
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
:deep(.vben-basic-table-header__toolbar) {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
:deep(.current-row) td {
|
||||
background: #e6f2ff !important;
|
||||
}
|
||||
</style>
|
||||
44
src/views/form/design/components/PreviewModal.vue
Normal file
44
src/views/form/design/components/PreviewModal.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div>
|
||||
<BasicModal @register="registerModal" v-bind="$attrs" title="预览">
|
||||
<SimpleForm
|
||||
ref="formRef"
|
||||
:key="show"
|
||||
:formProps="state.formProps"
|
||||
:formModel="state.formModel"
|
||||
/>
|
||||
</BasicModal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, provide } from 'vue';
|
||||
import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { buildOption } from '/@/utils/helper/designHelper';
|
||||
|
||||
const state = reactive({
|
||||
formProps: {},
|
||||
formModel: {},
|
||||
});
|
||||
provide<boolean>('isCustomForm', true);
|
||||
const show = ref(1);
|
||||
const formRef = ref();
|
||||
|
||||
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
|
||||
state.formProps = buildOption(JSON.parse(data.formJson).formJson, false);
|
||||
show.value += 1;
|
||||
|
||||
await formRef.value.setDefaultValue();
|
||||
formRef.value.resetFields();
|
||||
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
draggable: false,
|
||||
title: data.title,
|
||||
destroyOnClose: true,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
width: 800,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
371
src/views/form/design/components/components/CodeFirstModal.vue
Normal file
371
src/views/form/design/components/components/CodeFirstModal.vue
Normal file
@ -0,0 +1,371 @@
|
||||
<template>
|
||||
<BasicModal @register="registerModal" v-bind="$attrs" wrapClassName="form-modal">
|
||||
<template #title>
|
||||
<div class="step-form-form">
|
||||
<a href="https://fcdma.gdyditc.com/" target="_blank">
|
||||
<DesignLogo />
|
||||
</a>
|
||||
<span>•</span>
|
||||
<span>{{ t('表单设计') }} - {{ t('界面优先') }}</span>
|
||||
<a-steps :current="current" size="mini">
|
||||
<a-step :title="t('基础信息')" />
|
||||
<a-step :title="t('表单设计')" />
|
||||
<a-step :title="t('表单事件')" />
|
||||
<a-step :title="t('完整配置')" />
|
||||
<a-step :title="t('结构配置')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<a-button @click="handleStepPrev" v-show="current !== 0">{{ t('上一步') }}</a-button>
|
||||
<a-button type="primary" @click="handleStepNext" v-show="current < 4">
|
||||
{{ t('下一步') }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleSave" v-show="current === 4">
|
||||
{{ t('保存') }}
|
||||
</a-button>
|
||||
<a-button type="primary" danger @click="handleClose">{{ t('关闭') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="step-container">
|
||||
<BasicConfigStep ref="basicConfigStepRef" v-show="current === 0" />
|
||||
<FormDesignStep ref="formDesignStepRef" v-show="current === 1" />
|
||||
<FormEventStep ref="formEventStepRef" v-show="current === 2" />
|
||||
<EntireConfigStep ref="entireConfigStepRef" v-show="current === 3"/>
|
||||
<StructureConfigStep
|
||||
ref="structureConfigStepRef"
|
||||
v-show="current === 4"
|
||||
:isUpdate="isUpdate"
|
||||
:beforeTableNames="beforeTableNames"
|
||||
@validate-table="handleSave"
|
||||
/>
|
||||
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, inject, Ref, toRaw, watch } from 'vue';
|
||||
import { FormDesignStep, FormEventStep, StructureConfigStep,EntireConfigStep} from '/@/components/CreateCodeStep';
|
||||
import BasicConfigStep from '../BasicConfigStep.vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import {
|
||||
CustomFormConfig,
|
||||
CustomFormJson,
|
||||
GeneratorConfig,
|
||||
} from '/@/model/generator/generatorConfig';
|
||||
import { TableInfo } from '/@/components/Designer';
|
||||
import {
|
||||
addCodeFirstFormTemplate,
|
||||
updateCodeFirstFormTemplate,
|
||||
getFormTemplate,
|
||||
} from '/@/api/form/design';
|
||||
import { noHaveTableAndField } from '/@/components/Designer';
|
||||
import * as antd from '/@/components/Designer/src/types';
|
||||
import { FormTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
import { random } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { FormJson } from '/@/model/generator/codeGenerator';
|
||||
import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
|
||||
import { changeCompsApiConfig, changeEventApiConfig, getMainTable } from '/@/utils/event/design';
|
||||
import {ListConfig} from "/@/model/generator/listConfig";
|
||||
|
||||
const { t } = useI18n();
|
||||
const current = ref(0);
|
||||
|
||||
const basicConfigStepRef = ref();
|
||||
const formDesignStepRef = ref();
|
||||
const formEventStepRef = ref();
|
||||
const entireConfigStepRef = ref();
|
||||
const structureConfigStepRef = ref();
|
||||
const widgetForm = ref(JSON.parse(JSON.stringify(antd.widgetForm))); //FormDesignStep -> designer和StructureConfigStep页面使用
|
||||
const isUpdate = ref<boolean>(false);
|
||||
const tableInfo = ref<TableInfo[]>([]);
|
||||
const formId = ref<string>('');
|
||||
const beforeTableNames = ref<string[]>([]);
|
||||
const mainTableName = ref('table_' + random(10000, 99999));
|
||||
|
||||
let generatorConfig = reactive<CustomFormJson>({
|
||||
databaseId: '', //数据库id
|
||||
formJson: {} as FormJson,
|
||||
tableStructureConfigs: [],
|
||||
formEventConfig: {} as FormEventColumnConfig,
|
||||
isDataAuth: false,
|
||||
dataAuthList: [],
|
||||
});
|
||||
|
||||
let customFormConfig = reactive<CustomFormConfig>({
|
||||
name: '',
|
||||
category: '',
|
||||
formDesignType: 1,
|
||||
formType:'',
|
||||
formJson: generatorConfig,
|
||||
remark: '',
|
||||
isChange: false,
|
||||
});
|
||||
|
||||
provide<GeneratorConfig>('generatorConfig', generatorConfig as GeneratorConfig);
|
||||
provide<CustomFormConfig>('customFormConfig', customFormConfig);
|
||||
provide<Ref<TableInfo[]>>('tableInfo', tableInfo);
|
||||
provide<Ref<number>>('current', current); //当前步骤
|
||||
provide<string>('designType', 'code');
|
||||
provide('widgetForm', widgetForm);
|
||||
provide<Ref<string>>('mainTableName', mainTableName);
|
||||
provide<boolean>('isCustomForm', true); //是自定义表单
|
||||
provide<Ref<boolean>>('isFieldUpper', ref(false));
|
||||
|
||||
watch(
|
||||
() => generatorConfig,
|
||||
(val) => {
|
||||
customFormConfig.formJson = val;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
const emits = defineEmits(['success', 'register', 'close']);
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
isUpdate.value = !!data.isUpdate;
|
||||
formId.value = data.id;
|
||||
customFormConfig.isChange = isUpdate.value;
|
||||
if (formId.value) {
|
||||
getFormTemplateInfo();
|
||||
}
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
canFullscreen: false,
|
||||
defaultFullscreen: true,
|
||||
destroyOnClose: true,
|
||||
draggable: false,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
footer: null,
|
||||
closable: false,
|
||||
});
|
||||
});
|
||||
|
||||
async function getFormTemplateInfo() {
|
||||
const data = await getFormTemplate(formId.value);
|
||||
customFormConfig.name = data.name;
|
||||
customFormConfig.category = data.category;
|
||||
customFormConfig.formDesignType = data.formDesignType;
|
||||
customFormConfig.formJson = JSON.parse(data.formJson);
|
||||
customFormConfig.listConfig = JSON.parse(data.listConfig)||{} as ListConfig;
|
||||
customFormConfig.renderConfig =data.renderConfig;
|
||||
customFormConfig.remark = data.remark;
|
||||
|
||||
const { formJson,listConfig,renderConfig } = customFormConfig;
|
||||
|
||||
generatorConfig.databaseId = formJson.databaseId;
|
||||
generatorConfig.isDataAuth = formJson.isDataAuth;
|
||||
generatorConfig.dataAuthList = formJson.dataAuthList;
|
||||
generatorConfig.tableStructureConfigs = formJson.tableStructureConfigs;
|
||||
generatorConfig.formJson = formJson.formJson;
|
||||
generatorConfig.listConfig = listConfig;
|
||||
generatorConfig.renderConfig = renderConfig;
|
||||
generatorConfig.formEventConfig = formJson.formEventConfig!;
|
||||
generatorConfig.formJson.list = generatorConfig.formJson.list.filter(
|
||||
(x) => x.type !== 'hiddenComponent',
|
||||
);
|
||||
|
||||
getMainTableFirst(generatorConfig.formJson.list);
|
||||
widgetForm.value = generatorConfig.formJson;
|
||||
|
||||
basicConfigStepRef.value.setFieldsValue({
|
||||
name: customFormConfig?.name,
|
||||
category: customFormConfig?.category,
|
||||
remark: customFormConfig?.remark,
|
||||
databaseId: generatorConfig.databaseId,
|
||||
isDataAuth: generatorConfig.isDataAuth,
|
||||
dataAuthList: generatorConfig.dataAuthList,
|
||||
});
|
||||
|
||||
beforeTableNames.value = generatorConfig.tableStructureConfigs!.map((x) => x.tableName);
|
||||
}
|
||||
|
||||
function getMainTableFirst(list) {
|
||||
list.some((x) => {
|
||||
if (['tab', 'grid', 'card'].includes(x.type)) {
|
||||
for (const child of x.layout!) {
|
||||
return getMainTableFirst(child.list);
|
||||
}
|
||||
} else if (x.type === 'table-layout') {
|
||||
for (const child of x.layout!) {
|
||||
for (const el of child.list!) {
|
||||
return getMainTableFirst(el.children);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
x.type !== 'form' &&
|
||||
x.type !== 'one-for-one' &&
|
||||
!noHaveTableAndField.includes(x.type)
|
||||
) {
|
||||
mainTableName.value = x.bindTable;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
closeModal();
|
||||
emits('close');
|
||||
}
|
||||
|
||||
//上一步
|
||||
async function handleStepPrev() {
|
||||
current.value--;
|
||||
if(current.value==1){
|
||||
widgetForm.value = generatorConfig.formJson;
|
||||
}
|
||||
}
|
||||
//下一步
|
||||
async function handleStepNext() {
|
||||
if (current.value === 2) {
|
||||
entireConfigStepRef.value.initStep();
|
||||
current.value++;
|
||||
return;
|
||||
}
|
||||
|
||||
const isOk = await stepValidate[current.value]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
current.value++;
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
const isOk = await stepValidate[4]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tableFieldConfigs = getMainTable(generatorConfig.tableStructureConfigs);
|
||||
changeCompsApiConfig(generatorConfig!.formJson.list, 'code', tableFieldConfigs);
|
||||
changeEventApiConfig(generatorConfig!.formEventConfig, 'code', tableFieldConfigs);
|
||||
|
||||
if (
|
||||
generatorConfig.formJson?.hiddenComponent &&
|
||||
generatorConfig.formJson?.hiddenComponent.length
|
||||
) {
|
||||
generatorConfig.formJson.list.push(...generatorConfig.formJson.hiddenComponent);
|
||||
}
|
||||
if (isUpdate.value) {
|
||||
handleEditSuccess();
|
||||
} else {
|
||||
await addCodeFirstFormTemplate(toRaw(customFormConfig));
|
||||
closeModal();
|
||||
emits('success');
|
||||
emits('close');
|
||||
}
|
||||
}
|
||||
|
||||
async function handleEditSuccess() {
|
||||
await updateCodeFirstFormTemplate({ id: formId.value, ...toRaw(customFormConfig) });
|
||||
closeModal();
|
||||
emits('success');
|
||||
emits('close');
|
||||
}
|
||||
|
||||
const stepValidate = {
|
||||
//数据表配置 验证
|
||||
0: () => basicConfigStepRef.value.validateStep(),
|
||||
1: () => formDesignStepRef.value.validateStep(),
|
||||
2: () => formEventStepRef.value.validateStep(),
|
||||
3: () => entireConfigStepRef.value.validateStep(),
|
||||
4: () => structureConfigStepRef.value.validateStep(),
|
||||
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@keyframes rotation {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationReverse {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-process) {
|
||||
.ant-steps-item-icon {
|
||||
border: 2px solid #fff;
|
||||
line-height: 30px;
|
||||
animation: rotation 4s linear infinite;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
border: 2px dashed #1890ff;
|
||||
content: '';
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.ant-steps-icon {
|
||||
display: inline-block;
|
||||
animation: rotationReverse 4s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-form-content {
|
||||
padding: 24px;
|
||||
background-color: @component-background;
|
||||
}
|
||||
|
||||
.step-form-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
|
||||
a {
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
margin: 0 20px 0 -5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.ant-steps) {
|
||||
width: calc(100% - 750px);
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-container) {
|
||||
padding: 3px 0 3px 3px;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.step1 {
|
||||
padding: 0 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
317
src/views/form/design/components/components/DataFirstModal.vue
Normal file
317
src/views/form/design/components/components/DataFirstModal.vue
Normal file
@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<BasicModal @register="registerModal" v-bind="$attrs" wrapClassName="form-modal">
|
||||
<template #title>
|
||||
<div class="step-form-form">
|
||||
<a href="https://fcdma.gdyditc.com/" target="_blank">
|
||||
<DesignLogo />
|
||||
</a>
|
||||
<span>•</span>
|
||||
<span>{{ t('表单设计') }} - {{ t('数据优先') }}</span>
|
||||
<a-steps :current="current">
|
||||
<a-step :title="t('基础信息')" />
|
||||
<a-step :title="t('表单设计')" />
|
||||
<a-step :title="t('表单事件')" />
|
||||
<a-step :title="t('完整配置')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<ajax-error-icon />
|
||||
<a-button type="primary" @click="handleStepPrev" v-show="current !== 0">{{
|
||||
t('上一步')
|
||||
}}</a-button>
|
||||
<a-button type="primary" @click="handleStepNext" v-show="current < 3">{{
|
||||
t('下一步')
|
||||
}}</a-button>
|
||||
<a-button type="primary" @click="handleSave" v-show="current === 3">{{
|
||||
t('保存')
|
||||
}}</a-button>
|
||||
<a-button type="primary" danger @click="handleClose">{{ t('关闭') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="step-container">
|
||||
<BasicConfigStep ref="basicConfigStepRef" v-show="current === 0" />
|
||||
<FormDesignStep ref="formDesignStepRef" v-show="current === 1" />
|
||||
<FormEventStep ref="formEventStepRef" v-show="current === 2" />
|
||||
<EntireConfigStep ref="entireConfigStepRef" v-show="current === 3"/>
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, watch, Ref, toRaw, onUnmounted } from 'vue';
|
||||
import BasicConfigStep from '../BasicConfigStep.vue';
|
||||
import { FormDesignStep, FormEventStep,EntireConfigStep } from '/@/components/CreateCodeStep';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { CustomFormConfig, GeneratorConfig } from '/@/model/generator/generatorConfig';
|
||||
import { TableInfo } from '/@/components/Designer';
|
||||
import AjaxErrorIcon from '/@/components/SecondDev/AjaxErrorIcon.vue';
|
||||
import {
|
||||
addDataFirstFormTemplate,
|
||||
updateDataFirstFormTemplate,
|
||||
getFormTemplate,
|
||||
} from '/@/api/form/design';
|
||||
import { FormTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import * as antd from '/@/components/Designer/src/types';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
import useGlobalFlag from '/@/hooks/core/useGlobalFlag';
|
||||
import {ListConfig} from "/@/model/generator/listConfig";
|
||||
|
||||
const { t } = useI18n();
|
||||
const current = ref(0);
|
||||
|
||||
const basicConfigStepRef = ref();
|
||||
const formDesignStepRef = ref();
|
||||
const formEventStepRef = ref();
|
||||
const entireConfigStepRef = ref();
|
||||
|
||||
const tableInfo = ref<TableInfo[]>([]);
|
||||
const widgetForm = ref(JSON.parse(JSON.stringify(antd.widgetForm)));
|
||||
const isUpdate = ref<boolean>(false);
|
||||
const formId = ref<string>('');
|
||||
const emits = defineEmits(['success', 'register', 'close']);
|
||||
const globalFlag = useGlobalFlag();
|
||||
const { isEditorOpen } = globalFlag;
|
||||
|
||||
watch(current, () => {
|
||||
isEditorOpen.value = current.value === 1;
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
isEditorOpen.value = false;
|
||||
});
|
||||
|
||||
let generatorConfig = reactive<GeneratorConfig>({
|
||||
databaseId: '', //数据库id
|
||||
tableConfigs: [],
|
||||
formJson: {},
|
||||
formEventConfig: {},
|
||||
isDataAuth: false,
|
||||
dataAuthList: [],
|
||||
});
|
||||
let customFormConfig = reactive<CustomFormConfig>({
|
||||
name: '',
|
||||
category: '',
|
||||
formDesignType: 0,
|
||||
formType: '',
|
||||
formJson: generatorConfig,
|
||||
remark: '',
|
||||
});
|
||||
|
||||
provide<GeneratorConfig>('generatorConfig', generatorConfig);
|
||||
provide<CustomFormConfig>('customFormConfig', customFormConfig);
|
||||
provide<Ref<TableInfo[]>>('tableInfo', tableInfo);
|
||||
provide<string>('designType', 'data');
|
||||
provide('widgetForm', widgetForm);
|
||||
provide<Ref<number>>('current', current); //当前步骤
|
||||
provide<boolean>('isCustomForm', true); //是自定义表单
|
||||
|
||||
watch(
|
||||
() => generatorConfig,
|
||||
(val) => {
|
||||
customFormConfig.formJson = val;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner((data) => {
|
||||
isUpdate.value = !!data.isUpdate;
|
||||
formId.value = data.id;
|
||||
if (formId.value) getFormTemplateInfo();
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
canFullscreen: false,
|
||||
defaultFullscreen: true,
|
||||
destroyOnClose: true,
|
||||
draggable: false,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
footer: null,
|
||||
closable: false,
|
||||
});
|
||||
});
|
||||
|
||||
async function getFormTemplateInfo() {
|
||||
const data = await getFormTemplate(formId.value);
|
||||
customFormConfig.name = data.name;
|
||||
customFormConfig.category = data.category;
|
||||
customFormConfig.formDesignType = data.formDesignType;
|
||||
customFormConfig.formJson = JSON.parse(data.formJson);
|
||||
customFormConfig.listConfig = JSON.parse(data.listConfig)||{} as ListConfig;
|
||||
customFormConfig.renderConfig =data.renderConfig;
|
||||
customFormConfig.remark = data.remark;
|
||||
|
||||
const { formJson,listConfig,renderConfig } = customFormConfig;
|
||||
|
||||
generatorConfig.databaseId = formJson.databaseId;
|
||||
generatorConfig.isDataAuth = formJson.isDataAuth;
|
||||
generatorConfig.dataAuthList = formJson.dataAuthList;
|
||||
generatorConfig.tableConfigs = formJson.tableConfigs;
|
||||
generatorConfig.formJson = formJson.formJson;
|
||||
generatorConfig.listConfig = listConfig;
|
||||
generatorConfig.renderConfig = renderConfig;
|
||||
generatorConfig.formEventConfig = formJson.formEventConfig!;
|
||||
generatorConfig.formJson.list = generatorConfig.formJson.list.filter(
|
||||
(x) => x.type !== 'hiddenComponent',
|
||||
);
|
||||
widgetForm.value = generatorConfig.formJson;
|
||||
basicConfigStepRef.value.setFieldsValue({
|
||||
name: customFormConfig?.name,
|
||||
category: customFormConfig?.category,
|
||||
remark: customFormConfig?.remark,
|
||||
databaseId: generatorConfig.databaseId,
|
||||
isDataAuth: generatorConfig.isDataAuth,
|
||||
dataAuthList: generatorConfig.dataAuthList,
|
||||
});
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
closeModal();
|
||||
emits('close');
|
||||
}
|
||||
|
||||
//上一步
|
||||
function handleStepPrev() {
|
||||
current.value--;
|
||||
if(current.value==1){
|
||||
widgetForm.value = generatorConfig.formJson;
|
||||
}
|
||||
}
|
||||
//下一步
|
||||
async function handleStepNext() {
|
||||
const isOk = await stepValidate[current.value]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
current.value++;
|
||||
|
||||
if(current.value === 3){
|
||||
entireConfigStepRef.value.initStep();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function handleSave() {
|
||||
const isOk = await stepValidate[3]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
generatorConfig.formJson?.hiddenComponent &&
|
||||
generatorConfig.formJson?.hiddenComponent.length
|
||||
) {
|
||||
generatorConfig.formJson.list.push(...generatorConfig.formJson.hiddenComponent);
|
||||
}
|
||||
if (isUpdate.value) {
|
||||
await updateDataFirstFormTemplate({ id: formId.value, ...toRaw(customFormConfig) });
|
||||
} else {
|
||||
await addDataFirstFormTemplate(toRaw(customFormConfig));
|
||||
}
|
||||
|
||||
closeModal();
|
||||
emits('close');
|
||||
emits('success');
|
||||
}
|
||||
|
||||
const stepValidate = {
|
||||
//数据表配置 验证
|
||||
0: () => basicConfigStepRef.value.validateStep(),
|
||||
1: () => formDesignStepRef.value.validateStep(),
|
||||
2: () => formEventStepRef.value.validateStep(),
|
||||
3: () => entireConfigStepRef.value.validateStep(),
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@keyframes rotation {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationReverse {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-process) {
|
||||
.ant-steps-item-icon {
|
||||
border: 2px solid #fff;
|
||||
line-height: 30px;
|
||||
animation: rotation 4s linear infinite;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
border: 2px dashed #1890ff;
|
||||
content: '';
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.ant-steps-icon {
|
||||
display: inline-block;
|
||||
animation: rotationReverse 4s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-form-content {
|
||||
padding: 24px;
|
||||
background-color: @component-background;
|
||||
}
|
||||
|
||||
.step-form-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
|
||||
a {
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
margin: 0 20px 0 -5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.ant-steps) {
|
||||
width: calc(100% - 750px);
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-container) {
|
||||
padding: 3px 0 3px 3px;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-container {
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.step1 {
|
||||
padding: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,411 @@
|
||||
<template>
|
||||
<BasicModal @register="registerModal" v-bind="$attrs" wrapClassName="form-modal">
|
||||
<template #title>
|
||||
<div class="step-form-form">
|
||||
<a href="https://fcdma.gdyditc.com/" target="_blank">
|
||||
<DesignLogo />
|
||||
</a>
|
||||
<span>•</span>
|
||||
<span>{{ t('表单设计') }} - {{ t('简易模板') }}</span>
|
||||
<a-steps :current="current" size="mini">
|
||||
<a-step :title="t('基础信息')" />
|
||||
<a-step :title="t('表单设计')" />
|
||||
<a-step :title="t('表单事件')" />
|
||||
<a-step :title="t('完整配置')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<a-button @click="handleStepPrev" v-show="current !== 0">{{ t('上一步') }}</a-button>
|
||||
<a-button type="primary" @click="handleStepNext" v-show="current < 3">
|
||||
{{ t('下一步') }}
|
||||
</a-button>
|
||||
<a-button type="primary" @click="handleSave" v-show="current === 3">
|
||||
{{ t('保存') }}
|
||||
</a-button>
|
||||
<a-button type="primary" danger @click="handleClose">{{ t('关闭') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="step-container">
|
||||
<BasicConfigStep ref="basicConfigStepRef" v-show="current === 0" />
|
||||
<FormDesignStep ref="formDesignStepRef" v-show="current === 1" />
|
||||
<FormEventStep ref="formEventStepRef" v-show="current === 2" />
|
||||
<EntireConfigStep ref="entireConfigStepRef" v-show="current === 3"/>
|
||||
</div>
|
||||
</BasicModal>
|
||||
<TableNameModal @register="registerTableName" @success="handleEditSuccess" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, Ref, toRaw, watch, onMounted } from 'vue';
|
||||
import { FormDesignStep, FormEventStep,EntireConfigStep,TableNameModal } from '/@/components/CreateCodeStep';
|
||||
import BasicConfigStep from '../BasicConfigStep.vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { GeneratorConfig, CustomFormConfig } from '/@/model/generator/generatorConfig';
|
||||
import { TableInfo, upperFieldDb } from '/@/components/Designer';
|
||||
import { validateTableName, getMasterInfo } from '/@/api/system/generator';
|
||||
import {
|
||||
addCodeFirstFormTemplate,
|
||||
updateCodeFirstFormTemplate,
|
||||
getFormTemplate,
|
||||
} from '/@/api/form/design';
|
||||
import { FormTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import * as antd from '/@/components/Designer/src/types';
|
||||
import { random } from 'lodash-es';
|
||||
import { noHaveTableAndField } from '/@/components/Designer';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
import {ListConfig} from "/@/model/generator/listConfig";
|
||||
|
||||
const { t } = useI18n();
|
||||
const current = ref(0);
|
||||
|
||||
const basicConfigStepRef = ref();
|
||||
const formDesignStepRef = ref();
|
||||
const formEventStepRef = ref();
|
||||
const entireConfigStepRef = ref();
|
||||
|
||||
const widgetForm = ref(JSON.parse(JSON.stringify(antd.widgetForm))); //FormDesignStep -> designer和StructureConfigStep页面使用
|
||||
const mainTableName = ref('table_' + random(10000, 99999));
|
||||
|
||||
const tableInfo = ref<TableInfo[]>([]);
|
||||
const isUpdate = ref<boolean>(false);
|
||||
const formId = ref<string>('');
|
||||
const beforeTableNames = ref<string[]>([]);
|
||||
const isFieldUpper = ref<boolean>(false);
|
||||
|
||||
let generatorConfig = reactive<GeneratorConfig>({
|
||||
databaseId: 'master',
|
||||
formJson: {},
|
||||
tableStructureConfigs: [],
|
||||
formEventConfig: {},
|
||||
isDataAuth: false,
|
||||
dataAuthList: [],
|
||||
});
|
||||
|
||||
let customFormConfig = reactive<CustomFormConfig>({
|
||||
name: '',
|
||||
category: '',
|
||||
formDesignType: 2,
|
||||
formType:'',
|
||||
formJson: generatorConfig,
|
||||
remark: '',
|
||||
isChange: false,
|
||||
});
|
||||
|
||||
const [registerTableName, { openModal }] = useModal();
|
||||
|
||||
provide<GeneratorConfig>('generatorConfig', generatorConfig);
|
||||
provide<Ref<TableInfo[]>>('tableInfo', tableInfo);
|
||||
provide<CustomFormConfig>('customFormConfig', customFormConfig);
|
||||
provide<Ref<number>>('current', current); //当前步骤
|
||||
provide<string>('designType', 'template');
|
||||
provide('widgetForm', widgetForm);
|
||||
provide<Ref<string>>('mainTableName', mainTableName);
|
||||
provide<boolean>('isCustomForm', true); //是自定义表单
|
||||
provide<Ref<boolean>>('isFieldUpper', isFieldUpper);
|
||||
|
||||
watch(
|
||||
() => generatorConfig,
|
||||
(val) => {
|
||||
customFormConfig.formJson = val;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
},
|
||||
);
|
||||
const emits = defineEmits(['success', 'register', 'close']);
|
||||
|
||||
onMounted(async () => {
|
||||
const res = await getMasterInfo();
|
||||
isFieldUpper.value = upperFieldDb.includes(res?.dbType || '');
|
||||
mainTableName.value = isFieldUpper.value
|
||||
? mainTableName.value.toUpperCase()
|
||||
: mainTableName.value;
|
||||
});
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
isUpdate.value = !!data.isUpdate;
|
||||
formId.value = data.id;
|
||||
customFormConfig.isChange = isUpdate.value;
|
||||
if (formId.value) {
|
||||
getFormTemplateInfo();
|
||||
}
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
canFullscreen: false,
|
||||
defaultFullscreen: true,
|
||||
destroyOnClose: true,
|
||||
draggable: false,
|
||||
showOkBtn: false,
|
||||
showCancelBtn: false,
|
||||
footer: null,
|
||||
closable: false,
|
||||
});
|
||||
});
|
||||
|
||||
async function getFormTemplateInfo() {
|
||||
const data = await getFormTemplate(formId.value);
|
||||
customFormConfig.name = data.name;
|
||||
customFormConfig.category = data.category;
|
||||
customFormConfig.formDesignType = data.formDesignType;
|
||||
customFormConfig.formJson = JSON.parse(data.formJson);
|
||||
customFormConfig.listConfig = JSON.parse(data.listConfig)||{} as ListConfig;
|
||||
customFormConfig.renderConfig =data.renderConfig;
|
||||
customFormConfig.remark = data.remark;
|
||||
|
||||
const { formJson,listConfig,renderConfig } = customFormConfig;
|
||||
|
||||
generatorConfig.databaseId = formJson.databaseId;
|
||||
generatorConfig.isDataAuth = formJson.isDataAuth;
|
||||
generatorConfig.dataAuthList = formJson.dataAuthList;
|
||||
generatorConfig.tableStructureConfigs = formJson.tableStructureConfigs;
|
||||
generatorConfig.formJson = formJson.formJson;
|
||||
generatorConfig.listConfig = listConfig;
|
||||
generatorConfig.renderConfig = renderConfig;
|
||||
generatorConfig.formEventConfig = formJson.formEventConfig!;
|
||||
generatorConfig.formJson.list = generatorConfig.formJson.list.filter(
|
||||
(x) => x.type !== 'hiddenComponent',
|
||||
);
|
||||
beforeTableNames.value = generatorConfig.tableStructureConfigs?.map((x) => x.tableName) || [];
|
||||
getMainTableFirst(generatorConfig.formJson.list);
|
||||
|
||||
widgetForm.value = generatorConfig.formJson;
|
||||
|
||||
basicConfigStepRef.value.setFieldsValue({
|
||||
name: customFormConfig?.name,
|
||||
category: customFormConfig?.category,
|
||||
remark: customFormConfig?.remark,
|
||||
databaseId: generatorConfig.databaseId,
|
||||
isDataAuth: generatorConfig.isDataAuth,
|
||||
dataAuthList: generatorConfig.dataAuthList,
|
||||
});
|
||||
}
|
||||
|
||||
function getMainTableFirst(list) {
|
||||
list.some((x) => {
|
||||
if (['tab', 'grid', 'card'].includes(x.type)) {
|
||||
for (const child of x.layout!) {
|
||||
return getMainTableFirst(child.list);
|
||||
}
|
||||
} else if (x.type === 'table-layout') {
|
||||
for (const child of x.layout!) {
|
||||
for (const el of child.list!) {
|
||||
return getMainTableFirst(el.children);
|
||||
}
|
||||
}
|
||||
} else if (
|
||||
x.type !== 'form' &&
|
||||
x.type !== 'one-for-one' &&
|
||||
!noHaveTableAndField.includes(x.type)
|
||||
) {
|
||||
mainTableName.value = x.bindTable;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
closeModal();
|
||||
emits('close');
|
||||
}
|
||||
|
||||
//上一步
|
||||
function handleStepPrev() {
|
||||
current.value--;
|
||||
if(current.value==1){
|
||||
widgetForm.value = generatorConfig.formJson;
|
||||
}
|
||||
}
|
||||
//下一步
|
||||
async function handleStepNext() {
|
||||
const isOk = await stepValidate[current.value]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
current.value++;
|
||||
|
||||
if(current.value === 3){
|
||||
entireConfigStepRef.value.initStep();
|
||||
}
|
||||
}
|
||||
async function handleSave() {
|
||||
const isOk = await stepValidate[3]();
|
||||
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
const tableNames: string[] = generatorConfig.tableStructureConfigs!.map((x) => x.tableName);
|
||||
|
||||
const testTableNames = tableNames.filter((x) => {
|
||||
return !beforeTableNames.value.includes(x);
|
||||
});
|
||||
|
||||
if (!isUpdate.value || (isUpdate.value && testTableNames.length)) {
|
||||
const names = isUpdate.value ? testTableNames.toString() : tableNames.toString();
|
||||
validateName(names);
|
||||
} else {
|
||||
submitTemplate();
|
||||
}
|
||||
}
|
||||
|
||||
const validateName = (tableNames) => {
|
||||
const params = {
|
||||
id: 'master',
|
||||
tableNames,
|
||||
};
|
||||
validateTableName(params, 'none')
|
||||
.then(() => {
|
||||
submitTemplate();
|
||||
})
|
||||
.catch((err) => {
|
||||
if (!err) return;
|
||||
const info = err.message.split('[')[1];
|
||||
const existTableName = info.substring(0, info.length - 1).split(',');
|
||||
const newTableName: string[] = [];
|
||||
generatorConfig?.tableStructureConfigs!.map((table) => {
|
||||
const tableName = 'table_' + random(10000, 99999);
|
||||
if (existTableName.includes(table.tableName)) {
|
||||
table.tableName = tableName;
|
||||
}
|
||||
newTableName.push(tableName);
|
||||
generatorConfig.formJson.list.map((component) => {
|
||||
editTableName(component, existTableName, tableName);
|
||||
});
|
||||
});
|
||||
validateName(newTableName.toString());
|
||||
});
|
||||
};
|
||||
const editTableName = (component, existTableName, tableName) => {
|
||||
if (existTableName.includes(component.bindTable)) {
|
||||
component.bindTable = tableName;
|
||||
if (component.children || component.layout || component.list) {
|
||||
editTableName(component.children, existTableName, tableName);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const submitTemplate = async () => {
|
||||
if (
|
||||
generatorConfig.formJson?.hiddenComponent &&
|
||||
generatorConfig.formJson?.hiddenComponent.length
|
||||
) {
|
||||
generatorConfig.formJson.list.push(...generatorConfig.formJson.hiddenComponent);
|
||||
}
|
||||
if (isUpdate.value) {
|
||||
openModal();
|
||||
} else {
|
||||
await addCodeFirstFormTemplate(toRaw(customFormConfig));
|
||||
closeModal();
|
||||
emits('success');
|
||||
emits('close');
|
||||
}
|
||||
};
|
||||
|
||||
async function handleEditSuccess() {
|
||||
await updateCodeFirstFormTemplate({ id: formId.value, ...toRaw(customFormConfig) });
|
||||
closeModal();
|
||||
emits('success');
|
||||
emits('close');
|
||||
}
|
||||
|
||||
const stepValidate = {
|
||||
//数据表配置 验证
|
||||
0: () => basicConfigStepRef.value.validateStep(),
|
||||
1: () => formDesignStepRef.value.validateStep(),
|
||||
2: () => formEventStepRef.value.validateStep(),
|
||||
3: () => entireConfigStepRef.value.validateStep(),
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
@keyframes rotation {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationReverse {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-process) {
|
||||
.ant-steps-item-icon {
|
||||
border: 2px solid #fff;
|
||||
line-height: 30px;
|
||||
animation: rotation 4s linear infinite;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
border: 2px dashed #1890ff;
|
||||
content: '';
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: block;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
.ant-steps-icon {
|
||||
display: inline-block;
|
||||
animation: rotationReverse 4s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-form-content {
|
||||
padding: 24px;
|
||||
background-color: @component-background;
|
||||
}
|
||||
|
||||
.step-form-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
|
||||
a {
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
margin: 0 20px 0 -5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
:deep(.ant-steps) {
|
||||
width: calc(100% - 750px);
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-container) {
|
||||
padding: 3px 0 3px 3px;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.step1 {
|
||||
padding: 0 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
150
src/views/form/design/index.vue
Normal file
150
src/views/form/design/index.vue
Normal file
@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<PageWrapper dense contentFullHeight fixed-height contentClass="flex">
|
||||
<a-tabs v-model:activeKey="activeKey" class="custom-tab white">
|
||||
<a-tab-pane key="1" tab="零代码表单">
|
||||
<ZeroCodeTypeTabPane ref="zeroCodeTypeTabPaneRef" :dicId="dicId"/>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="生成器表单">
|
||||
<GeneratorTypeTabPane ref="generatorTypeTabPaneRef"/>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
||||
<DesignModal @register="registerDesignModal" @success="reload" />
|
||||
<HistoryModal @register="registerHistoryModal" />
|
||||
<CategoryModal title="表单" :dicId="dicId" @register="registerCategoryModal" @success="fetch" />
|
||||
<PreviewModal @register="registerPreviewModal" />
|
||||
<DataFirstModal
|
||||
v-if="state.isShowDataFirst"
|
||||
@register="registerDataFirst"
|
||||
@success="handleSuccess"
|
||||
@close="handleClose('isShowDataFirst')"
|
||||
/>
|
||||
<CodeFirstModal
|
||||
v-if="state.isShowCodeFirst"
|
||||
@register="registerCodeFirst"
|
||||
@success="handleSuccess"
|
||||
@close="handleClose('isShowCodeFirst')"
|
||||
/>
|
||||
<SimpleTemplateModal
|
||||
v-if="state.isShowSimpleTemplate"
|
||||
@register="registerSimpleTemplate"
|
||||
@success="handleSuccess"
|
||||
@close="handleClose('isShowSimpleTemplate')"
|
||||
/>
|
||||
<CodeGeneratorModal
|
||||
v-if="state.isShowCodeGenerator"
|
||||
@register="registerCodeGenerator"
|
||||
@close="handleClose('isShowCodeGenerator')"
|
||||
/>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { h, onMounted, ref, createVNode, reactive, computed,provide } from 'vue';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import DesignModal from './components/DesignModal.vue';
|
||||
import HistoryModal from './components/HistoryModal.vue';
|
||||
import { CategoryModal } from '/@/components/CategoryModal';
|
||||
import PreviewModal from './components/PreviewModal.vue';
|
||||
import DataFirstModal from './components/components/DataFirstModal.vue';
|
||||
import CodeFirstModal from './components/components/CodeFirstModal.vue';
|
||||
import SimpleTemplateModal from './components/components/SimpleTemplateModal.vue';
|
||||
import CodeGeneratorModal from './components/CodeGeneratorModal.vue';
|
||||
import { PlusOutlined, ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import ZeroCodeTypeTabPane from './tabpanes/ZeroCodeTypeTabPane.vue';
|
||||
import GeneratorTypeTabPane from './tabpanes/GeneratorTypeTabPane.vue';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const dicId = '1419276800524424444';
|
||||
const activeKey = ref('1');
|
||||
const zeroCodeTypeTabPaneRef=ref();
|
||||
const generatorTypeTabPaneRef=ref();
|
||||
const state = reactive({
|
||||
isShowDataFirst: true,
|
||||
isShowCodeFirst: true,
|
||||
isShowSimpleTemplate: true,
|
||||
isShowCodeGenerator: true,
|
||||
});
|
||||
|
||||
const { notification } = useMessage();
|
||||
const formType=ref();
|
||||
|
||||
const [registerDesignModal, { openModal: openDesignModal }] = useModal();
|
||||
const [registerHistoryModal, { openModal: openHistoryModal }] = useModal();
|
||||
const [registerCategoryModal, { openModal: openCategoryModal }] = useModal();
|
||||
const [registerPreviewModal, { openModal: openPreviewModal }] = useModal();
|
||||
const [registerDataFirst, { openModal: openDataFirstModal }] = useModal();
|
||||
const [registerCodeFirst, { openModal: openCodeFirstModal }] = useModal();
|
||||
const [registerSimpleTemplate, { openModal: openSimpleTemplateModal }] = useModal();
|
||||
const [registerCodeGenerator, { openModal: openCodeGeneratorModal }] = useModal();
|
||||
|
||||
provide('openDesignModal', openDesignModal);
|
||||
provide('openHistoryModal', openHistoryModal);
|
||||
provide('openCategoryModal', openCategoryModal);
|
||||
provide('openPreviewModal', openPreviewModal);
|
||||
provide('openDataFirstModal', openDataFirstModal);
|
||||
provide('openCodeFirstModal', openCodeFirstModal);
|
||||
provide('openSimpleTemplateModal', openSimpleTemplateModal);
|
||||
provide('openCodeGeneratorModal', openCodeGeneratorModal);
|
||||
|
||||
provide<number>('formType', formType);
|
||||
provide('noticeInfo', noticeInfo);
|
||||
|
||||
function handleSuccess() {
|
||||
if(activeKey.value=='1'){
|
||||
zeroCodeTypeTabPaneRef.value.reload();
|
||||
}else if(activeKey.value=='2'){
|
||||
generatorTypeTabPaneRef.value.reload();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function handleClose(modal) {
|
||||
state[modal] = !state[modal];
|
||||
setTimeout(() => {
|
||||
state[modal] = !state[modal];
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function noticeInfo(info: string) {
|
||||
notification.warning({
|
||||
message: t('提示'),
|
||||
description: t(`请先选择要{notice}的数据项`, { notice: info }),
|
||||
}); //提示消息
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.toolbar-defined {
|
||||
:deep(.ant-btn) {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.custom-tab.white){
|
||||
background-color:white!important;
|
||||
}
|
||||
:deep(.ant-tabs-nav){
|
||||
padding:0px 10px!important;
|
||||
}
|
||||
|
||||
:deep(.ant-tabs-content){
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// :deep(.ant-col-15) {
|
||||
// flex: 0 0 calc(100% - 185px);
|
||||
// max-width: initial;
|
||||
// }
|
||||
|
||||
// :deep(.ant-table-wrapper .ant-table-title) {
|
||||
// padding-bottom: 0 !important;
|
||||
// }
|
||||
|
||||
// :deep(.ant-table-container) {
|
||||
// height: calc(100% - 110px);
|
||||
// }
|
||||
</style>
|
||||
255
src/views/form/design/tabpanes/GeneratorTypeTabPane.vue
Normal file
255
src/views/form/design/tabpanes/GeneratorTypeTabPane.vue
Normal file
@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<div style="display:flex;background-color:white;height: 100%">
|
||||
<div
|
||||
class="w-1/3 xl:w-1/4 overflow-hidden bg-white h-full"
|
||||
:style="{ 'border-right': '1px solid #e5e7eb' }"
|
||||
>
|
||||
<BasicTree
|
||||
:title="t('生成器类型')"
|
||||
:clickRowToExpand="true"
|
||||
:treeData="treeData"
|
||||
:fieldNames="{ key: 'id', title: 'name' }"
|
||||
@select="handleSelect"
|
||||
/>
|
||||
</div>
|
||||
<BasicTable @register="registerTable" class="w-2/3 xl:w-3/4">
|
||||
<template #toolbar>
|
||||
<div class="toolbar-defined">
|
||||
<a-button @click="previewForm" v-auth="'form-design:previewForm'">{{
|
||||
t('预览表单')
|
||||
}}</a-button>
|
||||
<a-button @click="queryHistory">{{ t('历史记录') }}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
icon: 'clarity:note-edit-line',
|
||||
auth: 'form-design:edit',
|
||||
onClick: handleEdit.bind(null, record,0),
|
||||
}
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, onMounted, ref, createVNode, reactive, computed,provide,inject } from 'vue';
|
||||
import { BasicTable, useTable, TableAction, FormSchema, BasicColumn } from '/@/components/Table';
|
||||
import {
|
||||
getFormTemplatePage,
|
||||
deleteFormTemplate,
|
||||
updateFormTemplateStatus,
|
||||
getFormTemplate,
|
||||
} from '/@/api/form/design';
|
||||
import { FormTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import { BasicTree, TreeItem } from '/@/components/Tree';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
const { notification } = useMessage();
|
||||
const { t } = useI18n();
|
||||
|
||||
const treeData = ref<TreeItem[]>([
|
||||
{ "id":'0',name:'数据优先模板'},
|
||||
{ "id":'1',name:'界面优先模板'},
|
||||
{ "id":'2',name:'简易模板'}
|
||||
]);
|
||||
|
||||
const selectId = ref('');
|
||||
const selectedKeys = ref<string[]>([]);
|
||||
|
||||
const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'keyword',
|
||||
label: t('关键字'),
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
placeholder: t('请输入关键字'),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const columns: BasicColumn[] = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: t('名称'),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
dataIndex: 'formDesignType',
|
||||
title: t('模板类型'),
|
||||
width: 120,
|
||||
align: 'left',
|
||||
customRender: ({ record }) => {
|
||||
if(record.formDesignType==0){
|
||||
return "数据优先模板";
|
||||
}else if(record.formDesignType==1){
|
||||
return "界面优先模板";
|
||||
}else if(record.formDesignType==2){
|
||||
return "简易模板";
|
||||
}else{
|
||||
return '';
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'createUserName',
|
||||
title: t('创建人'),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
dataIndex: 'createDate',
|
||||
title: t('创建时间'),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
dataIndex: 'remark',
|
||||
align: 'left',
|
||||
title: t('备注'),
|
||||
},
|
||||
];
|
||||
|
||||
const formConfig = {
|
||||
rowProps: {
|
||||
gutter: 16,
|
||||
},
|
||||
schemas: searchFormSchema,
|
||||
fieldMapToTime: [],
|
||||
showResetButton: false,
|
||||
};
|
||||
|
||||
const [registerTable, { reload:reload, setSelectedRowKeys:setSelectedRowKeys}] = useTable({
|
||||
api: getFormTemplatePage,
|
||||
rowKey: 'id',
|
||||
title: '表单列表',
|
||||
columns:columns,
|
||||
formConfig,
|
||||
beforeFetch: (params) => {
|
||||
//发送请求默认新增 左边树结构所选id
|
||||
return { ...params, category: selectId.value, type: FormTypeEnum.SYSTEM_FORM };
|
||||
},
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
striped: false,
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
},
|
||||
rowSelection: {
|
||||
onChange: onSelectChange,
|
||||
},
|
||||
customRow,
|
||||
tableSetting: {
|
||||
size: false,
|
||||
setting: false,
|
||||
},
|
||||
});
|
||||
|
||||
const formId = computed(() => {
|
||||
return selectedKeys.value && selectedKeys.value.length
|
||||
? selectedKeys.value[selectedKeys.value.length - 1]
|
||||
: '';
|
||||
});
|
||||
|
||||
const openDesignModal = inject('openDesignModal');
|
||||
const openHistoryModal = inject('openHistoryModal');
|
||||
const openCategoryModal = inject('openCategoryModal');
|
||||
const openPreviewModal = inject('openPreviewModal');
|
||||
const openDataFirstModal = inject('openDataFirstModal');
|
||||
const openCodeFirstModal = inject('openCodeFirstModal');
|
||||
const openSimpleTemplateModal = inject('openSimpleTemplateModal');
|
||||
const openCodeGeneratorModal = inject('openCodeGeneratorModal');
|
||||
const formType = inject('formType');
|
||||
const noticeInfo = inject('noticeInfo');
|
||||
|
||||
function onSelectChange(rowKeys: string[]) {
|
||||
selectedKeys.value = rowKeys;
|
||||
setSelectedRowKeys(selectedKeys.value);
|
||||
}
|
||||
|
||||
function customRow(record: Recordable) {
|
||||
return {
|
||||
onClick: () => {
|
||||
let selectedRowKeys = [...selectedKeys.value];
|
||||
if (selectedRowKeys.indexOf(record.id) >= 0) {
|
||||
let index = selectedRowKeys.indexOf(record.id);
|
||||
selectedRowKeys.splice(index, 1);
|
||||
} else {
|
||||
selectedRowKeys.push(record.id);
|
||||
}
|
||||
selectedKeys.value = selectedRowKeys;
|
||||
setSelectedRowKeys(selectedRowKeys);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable,fType:number) {
|
||||
formType.value=fType;
|
||||
switch (record.formDesignType) {
|
||||
case 0:
|
||||
openDataFirstModal(true, {
|
||||
id: record.id,
|
||||
isUpdate: true,
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
openCodeFirstModal(true, {
|
||||
id: record.id,
|
||||
isUpdate: true,
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
openSimpleTemplateModal(true, {
|
||||
id: record.id,
|
||||
isUpdate: true,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: '该表单缺少模板类型',
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function handleSelect(selectIds) {
|
||||
selectId.value = selectIds[0];
|
||||
reload({ searchInfo: { category: selectIds[0] } });
|
||||
}
|
||||
|
||||
async function previewForm() {
|
||||
if (!formId.value) {
|
||||
noticeInfo('预览');
|
||||
return;
|
||||
}
|
||||
const templateJson = await getFormTemplate(formId.value);
|
||||
openPreviewModal(true, { title: t('预览'), formJson: templateJson.formJson });
|
||||
}
|
||||
|
||||
async function queryHistory() {
|
||||
if (!formId.value) {
|
||||
notification.warning({
|
||||
message: t('提示'),
|
||||
description: t(`请先选中一行后再查看当前表单历史记录!`),
|
||||
});
|
||||
return;
|
||||
}
|
||||
openHistoryModal(true, { title: t('历史记录'), formId: formId.value });
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
reload
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
356
src/views/form/design/tabpanes/ZeroCodeTypeTabPane.vue
Normal file
356
src/views/form/design/tabpanes/ZeroCodeTypeTabPane.vue
Normal file
@ -0,0 +1,356 @@
|
||||
<template>
|
||||
<div style="display:flex;background-color:white;height: 100%">
|
||||
<div
|
||||
class="w-1/3 xl:w-1/4 overflow-hidden bg-white h-full"
|
||||
:style="{ 'border-right': '1px solid #e5e7eb' }"
|
||||
>
|
||||
<BasicTree
|
||||
:title="t('表单分类')"
|
||||
:clickRowToExpand="true"
|
||||
:treeData="treeData"
|
||||
:fieldNames="{ key: 'id', title: 'name' }"
|
||||
@select="handleSelect"
|
||||
/>
|
||||
</div>
|
||||
<BasicTable @register="registerTable" class="w-2/3 xl:w-3/4">
|
||||
<template #toolbar>
|
||||
<div class="toolbar-defined">
|
||||
<a-button type="primary" @click="handleCreate" v-auth="'form-design:add'">
|
||||
<template #icon><PlusOutlined /></template>
|
||||
{{ t('新增') }}
|
||||
</a-button>
|
||||
<a-button @click="handleDelete" v-auth="'form-design:batchDelete'">{{
|
||||
t('批量删除')
|
||||
}}</a-button>
|
||||
<a-button @click="previewForm" v-auth="'form-design:previewForm'">{{
|
||||
t('预览表单')
|
||||
}}</a-button>
|
||||
<a-button @click="queryHistory">{{ t('历史记录') }}</a-button>
|
||||
<a-button @click="handleCategory" v-auth="'form-design:classifyMGT'">{{
|
||||
t('分类管理')
|
||||
}}</a-button>
|
||||
<a-button @click="handleCodeGenerator" v-auth="'form-design:generatedCode'">{{
|
||||
t('生成代码')
|
||||
}}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
icon: 'clarity:note-edit-line',
|
||||
auth: 'form-design:edit',
|
||||
onClick: handleEdit.bind(null, record,1),
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:delete-outlined',
|
||||
auth: 'form-design:delete',
|
||||
color: 'error',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, onMounted, ref, createVNode, reactive, computed,provide,inject } from 'vue';
|
||||
import { BasicTable, useTable, TableAction, FormSchema, BasicColumn } from '/@/components/Table';
|
||||
import {
|
||||
getFormTemplatePage,
|
||||
deleteFormTemplate,
|
||||
updateFormTemplateStatus,
|
||||
getFormTemplate,
|
||||
} from '/@/api/form/design';
|
||||
import { BasicTree, TreeItem } from '/@/components/Tree';
|
||||
import { FormTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { getDicDetailList } from '/@/api/system/dic';
|
||||
import { Switch, Modal } from 'ant-design-vue';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
dicId:String
|
||||
})
|
||||
|
||||
|
||||
const { notification } = useMessage();
|
||||
const { t } = useI18n();
|
||||
|
||||
const treeData = ref<TreeItem[]>([]);
|
||||
const selectId = ref('');
|
||||
const selectedKeys = ref<string[]>([]);
|
||||
|
||||
const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'keyword',
|
||||
label: t('关键字'),
|
||||
component: 'Input',
|
||||
componentProps: {
|
||||
placeholder: t('请输入关键字'),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const columns: BasicColumn[] = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: t('名称'),
|
||||
align: 'left',
|
||||
},
|
||||
|
||||
{
|
||||
dataIndex: 'categoryName',
|
||||
title: t('分类'),
|
||||
align: 'left',
|
||||
},
|
||||
|
||||
{
|
||||
dataIndex: 'enabledMark',
|
||||
title: t('状态'),
|
||||
width: 120,
|
||||
align: 'left',
|
||||
customRender: ({ record }) => {
|
||||
if (!Reflect.has(record, 'pendingStatus')) {
|
||||
record.pendingStatus = false;
|
||||
}
|
||||
return h(Switch, {
|
||||
checked: record.enabledMark === 1,
|
||||
checkedChildren: t('已启用'),
|
||||
unCheckedChildren: t('已禁用'),
|
||||
loading: record.pendingStatus,
|
||||
onChange(checked: boolean) {
|
||||
record.pendingStatus = true;
|
||||
const newStatus = checked ? 1 : 0;
|
||||
const { createMessage } = useMessage();
|
||||
updateFormTemplateStatus(record.id, newStatus)
|
||||
.then(() => {
|
||||
record.enabledMark = newStatus;
|
||||
createMessage.success(t('已成功修改状态'));
|
||||
})
|
||||
.catch(() => {
|
||||
createMessage.error(t('修改状态失败'));
|
||||
})
|
||||
.finally(() => {
|
||||
record.pendingStatus = false;
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
dataIndex: 'createUserName',
|
||||
title: t('创建人'),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
dataIndex: 'createDate',
|
||||
title: t('创建时间'),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
dataIndex: 'remark',
|
||||
align: 'left',
|
||||
title: t('备注'),
|
||||
},
|
||||
];
|
||||
|
||||
const formConfig = {
|
||||
rowProps: {
|
||||
gutter: 16,
|
||||
},
|
||||
schemas: searchFormSchema,
|
||||
fieldMapToTime: [],
|
||||
showResetButton: false,
|
||||
};
|
||||
|
||||
const [registerTable, { reload, setSelectedRowKeys }] = useTable({
|
||||
api: getFormTemplatePage,
|
||||
rowKey: 'id',
|
||||
title: '表单列表',
|
||||
columns,
|
||||
formConfig,
|
||||
beforeFetch: (params) => {
|
||||
//发送请求默认新增 左边树结构所选id
|
||||
return { ...params, category: selectId.value, type: FormTypeEnum.CUSTOM_FORM };
|
||||
},
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
striped: false,
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
},
|
||||
rowSelection: {
|
||||
onChange: onSelectChange,
|
||||
},
|
||||
customRow,
|
||||
tableSetting: {
|
||||
size: false,
|
||||
setting: false,
|
||||
},
|
||||
});
|
||||
|
||||
const formId = computed(() => {
|
||||
return selectedKeys.value && selectedKeys.value.length
|
||||
? selectedKeys.value[selectedKeys.value.length - 1]
|
||||
: '';
|
||||
});
|
||||
|
||||
const openDesignModal = inject('openDesignModal');
|
||||
const openHistoryModal = inject('openHistoryModal');
|
||||
const openCategoryModal = inject('openCategoryModal');
|
||||
const openPreviewModal = inject('openPreviewModal');
|
||||
const openDataFirstModal = inject('openDataFirstModal');
|
||||
const openCodeFirstModal = inject('openCodeFirstModal');
|
||||
const openSimpleTemplateModal = inject('openSimpleTemplateModal');
|
||||
const openCodeGeneratorModal = inject('openCodeGeneratorModal');
|
||||
const formType = inject('formType');
|
||||
const noticeInfo = inject('noticeInfo');
|
||||
|
||||
function onSelectChange(rowKeys: string[]) {
|
||||
selectedKeys.value = rowKeys;
|
||||
setSelectedRowKeys(selectedKeys.value);
|
||||
}
|
||||
|
||||
function customRow(record: Recordable) {
|
||||
return {
|
||||
onClick: () => {
|
||||
let selectedRowKeys = [...selectedKeys.value];
|
||||
if (selectedRowKeys.indexOf(record.id) >= 0) {
|
||||
let index = selectedRowKeys.indexOf(record.id);
|
||||
selectedRowKeys.splice(index, 1);
|
||||
} else {
|
||||
selectedRowKeys.push(record.id);
|
||||
}
|
||||
selectedKeys.value = selectedRowKeys;
|
||||
setSelectedRowKeys(selectedRowKeys);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function handleCreate() {
|
||||
openDesignModal(true, {
|
||||
title: t('添加表单'),
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable,fType:number) {
|
||||
formType.value=fType;
|
||||
switch (record.formDesignType) {
|
||||
case 0:
|
||||
openDataFirstModal(true, {
|
||||
id: record.id,
|
||||
isUpdate: true,
|
||||
});
|
||||
break;
|
||||
case 1:
|
||||
openCodeFirstModal(true, {
|
||||
id: record.id,
|
||||
isUpdate: true,
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
openSimpleTemplateModal(true, {
|
||||
id: record.id,
|
||||
isUpdate: true,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: '该表单缺少模板类型',
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function handleDelete(record: Recordable = {}) {
|
||||
const ids = record.id ? [record.id] : selectedKeys.value;
|
||||
if (!ids.length) {
|
||||
noticeInfo('删除');
|
||||
return;
|
||||
}
|
||||
Modal.confirm({
|
||||
title: t('提示'),
|
||||
icon: createVNode(ExclamationCircleOutlined),
|
||||
content: t('确定要删除所选项吗?'),
|
||||
onOk() {
|
||||
deleteFormTemplate(ids).then(() => {
|
||||
reload();
|
||||
notification.success({
|
||||
message: t('提示'),
|
||||
description: t('删除成功'),
|
||||
});
|
||||
});
|
||||
},
|
||||
onCancel() {},
|
||||
okText: t('确认'),
|
||||
cancelText: t('取消'),
|
||||
});
|
||||
}
|
||||
|
||||
function handleSelect(selectIds) {
|
||||
selectId.value = selectIds[0];
|
||||
reload({ searchInfo: { category: selectIds[0] } });
|
||||
}
|
||||
|
||||
function handleCodeGenerator() {
|
||||
if (!formId.value) {
|
||||
noticeInfo('生成');
|
||||
return;
|
||||
}
|
||||
openCodeGeneratorModal(true, { formId: formId.value });
|
||||
}
|
||||
|
||||
async function previewForm() {
|
||||
if (!formId.value) {
|
||||
noticeInfo('预览');
|
||||
return;
|
||||
}
|
||||
const templateJson = await getFormTemplate(formId.value);
|
||||
openPreviewModal(true, { title: t('预览'), formJson: templateJson.formJson });
|
||||
}
|
||||
|
||||
async function queryHistory() {
|
||||
if (!formId.value) {
|
||||
notification.warning({
|
||||
message: t('提示'),
|
||||
description: t(`请先选中一行后再查看当前表单历史记录!`),
|
||||
});
|
||||
return;
|
||||
}
|
||||
openHistoryModal(true, { title: t('历史记录'), formId: formId.value });
|
||||
}
|
||||
|
||||
async function fetch() {
|
||||
treeData.value = (await getDicDetailList({
|
||||
itemId: props.dicId,
|
||||
})) as unknown as TreeItem[];
|
||||
}
|
||||
|
||||
function handleCategory() {
|
||||
openCategoryModal(true, { title: t('表单分类管理') });
|
||||
}
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
fetch();
|
||||
});
|
||||
|
||||
defineExpose({
|
||||
reload
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
|
||||
</style>
|
||||
119
src/views/form/release/components/BasicConfigStep.vue
Normal file
119
src/views/form/release/components/BasicConfigStep.vue
Normal file
@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div class="step1-form">
|
||||
<BasicForm @register="register" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { inject } from 'vue';
|
||||
import { getFormTemplateList } from '/@/api/form/design';
|
||||
import { FormSchema, useForm, BasicForm } from '/@/components/Form';
|
||||
import { FormReleaseConfig } from '/@/model/generator/generatorConfig';
|
||||
import { FormTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
|
||||
const { notification } = useMessage();
|
||||
|
||||
const { t } = useI18n();
|
||||
defineEmits(['register']);
|
||||
|
||||
const formReleaseConfig = inject<FormReleaseConfig>('formReleaseConfig') as FormReleaseConfig;
|
||||
|
||||
const formSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'code',
|
||||
label: t('菜单编号'),
|
||||
required: true,
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
label: t('菜单名称'),
|
||||
required: true,
|
||||
component: 'Input',
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
field: 'parentId',
|
||||
label: t('上级菜单'),
|
||||
component: 'MenuSelect',
|
||||
required: process.env.NODE_ENV === 'production',
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
field: 'formId',
|
||||
label: t('表单选择'),
|
||||
required: true,
|
||||
component: 'ApiSelect',
|
||||
componentProps: {
|
||||
api: getFormTemplateList,
|
||||
// use name as label
|
||||
labelField: 'name',
|
||||
// use id as value
|
||||
valueField: 'id',
|
||||
getPopupContainer: () => document.body,
|
||||
params: {
|
||||
type: FormTypeEnum.CUSTOM_FORM,
|
||||
},
|
||||
showSearch: true,
|
||||
},
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
field: 'sortCode',
|
||||
label: t('排序'),
|
||||
required: true,
|
||||
component: 'InputNumber',
|
||||
componentProps: {
|
||||
style: { width: '100%' },
|
||||
},
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
{
|
||||
field: 'icon',
|
||||
label: t('图标'),
|
||||
required: true,
|
||||
component: 'IconPicker',
|
||||
colProps: { span: 12 },
|
||||
},
|
||||
|
||||
{
|
||||
field: 'remark',
|
||||
label: t('备注'),
|
||||
component: 'InputTextArea',
|
||||
colProps: { span: 24 },
|
||||
},
|
||||
];
|
||||
const [register, { validate, setFieldsValue }] = useForm({
|
||||
labelWidth: 100,
|
||||
schemas: formSchema,
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
|
||||
//验证当前步骤的数据
|
||||
const validateStep = async (): Promise<boolean> => {
|
||||
try {
|
||||
const formData = await validate();
|
||||
if (formData.code.length > 10) {
|
||||
notification.error({
|
||||
message: t('提示'),
|
||||
description: '编号长度不能超过10个字符',
|
||||
}); //提示消息
|
||||
return false;
|
||||
}
|
||||
formReleaseConfig.menuConfig.code = formData.code;
|
||||
formReleaseConfig.menuConfig.name = formData.name;
|
||||
formReleaseConfig.menuConfig.parentId = formData.parentId;
|
||||
formReleaseConfig.menuConfig.remark = formData.remark;
|
||||
formReleaseConfig.menuConfig.sortCode = formData.sortCode;
|
||||
formReleaseConfig.menuConfig.icon = formData.icon;
|
||||
formReleaseConfig.formId = formData.formId;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
defineExpose({ validateStep, setFieldsValue });
|
||||
</script>
|
||||
315
src/views/form/release/components/ReleaseModal.vue
Normal file
315
src/views/form/release/components/ReleaseModal.vue
Normal file
@ -0,0 +1,315 @@
|
||||
<template>
|
||||
<BasicModal @register="registerModal" v-bind="$attrs" wrapClassName="form-modal">
|
||||
<template #title>
|
||||
<div class="step-form-form">
|
||||
<a href="https://fcdma.gdyditc.com/" target="_blank">
|
||||
<DesignLogo />
|
||||
</a>
|
||||
<span>•</span>
|
||||
<span class="title">{{ title }}</span>
|
||||
<a-steps :current="current">
|
||||
<a-step :title="t('基础信息')" />
|
||||
<a-step :title="t('界面设计')" />
|
||||
</a-steps>
|
||||
<div class="btn-box">
|
||||
<a-button type="primary" @click="handleStepPrev" v-show="current === 1">{{
|
||||
t('上一步')
|
||||
}}</a-button>
|
||||
<a-button type="primary" @click="handleStepNext" v-show="current === 0">{{
|
||||
t('下一步')
|
||||
}}</a-button>
|
||||
<a-button type="primary" @click="handleSave" v-show="current === 1">{{
|
||||
t('完成')
|
||||
}}</a-button>
|
||||
<a-button type="primary" danger @click="handleClose">{{ t('关闭') }}</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="step-container">
|
||||
<BasicConfigStep ref="basicConfigStepRef" v-show="current === 0" />
|
||||
<ViewDesignStep ref="viewDesignStepRef" v-show="current === 1" :isUpdate="isUpdate" />
|
||||
</div>
|
||||
</BasicModal>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, provide, Ref, toRaw } from 'vue';
|
||||
import BasicConfigStep from './BasicConfigStep.vue';
|
||||
import ViewDesignStep from '/@/components/CreateCodeStep/src/ViewDesignStep.vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { FormReleaseConfig, GeneratorConfig } from '/@/model/generator/generatorConfig';
|
||||
import { FieldInfo, TableInfo } from '/@/components/Designer';
|
||||
import { getFormTemplate } from '/@/api/form/design';
|
||||
import { getDatabaselinkMultiTableColumns } from '/@/api/system/databaselink';
|
||||
import { addFormRelease, getFormRelease, updateFormRelease } from '/@/api/form/release';
|
||||
import { JavaTypeConvertTsType } from '/@/utils/helper/designHelper';
|
||||
import { FormDesignTypeEnum } from '/@/enums/formtypeEnum';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
|
||||
const { t } = useI18n();
|
||||
const current = ref(0);
|
||||
const isFormEdit = ref<boolean>(false);
|
||||
|
||||
const emit = defineEmits(['success', 'register', 'close']);
|
||||
|
||||
const formIdCache = ref(``);
|
||||
|
||||
const basicConfigStepRef = ref();
|
||||
const viewDesignStepRef = ref();
|
||||
|
||||
const tableInfo = ref<TableInfo[]>([]);
|
||||
|
||||
const isUpdate = ref<boolean>(false);
|
||||
const releaseId = ref<string>('');
|
||||
const menuId = ref<string>('');
|
||||
const designType = ref<string>('');
|
||||
const title = ref<string>('');
|
||||
|
||||
let generatorConfig = reactive<GeneratorConfig>({
|
||||
listConfig: {
|
||||
listTitle: '',
|
||||
isLeftMenu: false,
|
||||
queryConfigs: [],
|
||||
leftMenuConfig: {
|
||||
datasourceType: 'static',
|
||||
listFieldName: undefined,
|
||||
apiConfig: {},
|
||||
dictionaryItemId: undefined,
|
||||
menuName: '',
|
||||
parentIcon: '',
|
||||
childIcon: '',
|
||||
staticData: [],
|
||||
},
|
||||
columnConfigs: [],
|
||||
buttonConfigs: [],
|
||||
defaultOrder: true,
|
||||
orderBy: '',
|
||||
isPage: true,
|
||||
},
|
||||
menuConfig: {},
|
||||
});
|
||||
|
||||
let formReleaseConfig = reactive<FormReleaseConfig>({
|
||||
formId: '',
|
||||
listConfig: {},
|
||||
menuConfig: generatorConfig.menuConfig,
|
||||
});
|
||||
|
||||
provide<GeneratorConfig>('generatorConfig', generatorConfig);
|
||||
provide<FormReleaseConfig>('formReleaseConfig', formReleaseConfig);
|
||||
provide<Ref<TableInfo[]>>('tableInfo', tableInfo);
|
||||
provide<Ref<number>>('current', current); //当前步骤
|
||||
provide<Ref<string>>('designType', designType);
|
||||
provide<boolean>('isCustomForm', true); //是自定义表单
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
isFormEdit.value = !!data.isUpdate;
|
||||
isUpdate.value = !!data.isUpdate;
|
||||
releaseId.value = data.id;
|
||||
title.value = data.title;
|
||||
setModalProps({
|
||||
confirmLoading: false,
|
||||
canFullscreen: false,
|
||||
defaultFullscreen: true,
|
||||
draggable: false,
|
||||
destroyOnClose: true,
|
||||
maskClosable: false,
|
||||
footer: null,
|
||||
closable: false,
|
||||
});
|
||||
if (isUpdate.value) {
|
||||
const res = await getFormRelease(releaseId.value);
|
||||
const configJson = JSON.parse(res.configJson);
|
||||
const menuConfig = { ...configJson.menuConfig, formId: res.formId };
|
||||
menuId.value = res.menuId;
|
||||
generatorConfig.listConfig = cloneDeep(configJson.listConfig);
|
||||
//基础信息赋值
|
||||
basicConfigStepRef.value.setFieldsValue(menuConfig);
|
||||
}
|
||||
});
|
||||
|
||||
async function getReleseInfo() {
|
||||
if (formReleaseConfig.formId && formIdCache.value !== formReleaseConfig.formId) {
|
||||
formIdCache.value = formReleaseConfig.formId;
|
||||
const res = await getFormTemplate(formReleaseConfig.formId);
|
||||
const formJson = JSON.parse(res.formJson);
|
||||
const selectTableName = formJson.tableConfigs?.map((item) => item.tableName);
|
||||
|
||||
switch (res.formDesignType) {
|
||||
case FormDesignTypeEnum.DATA_FIRST:
|
||||
designType.value = 'data';
|
||||
break;
|
||||
case FormDesignTypeEnum.CODE_FIRST:
|
||||
designType.value = 'code';
|
||||
break;
|
||||
case FormDesignTypeEnum.SIMPLE_TEMPLATE:
|
||||
designType.value = 'template';
|
||||
break;
|
||||
}
|
||||
|
||||
generatorConfig.formJson = formJson.formJson;
|
||||
generatorConfig.tableStructureConfigs = formJson.tableStructureConfigs;
|
||||
if (designType.value !== 'data') return;
|
||||
try {
|
||||
const result = await getDatabaselinkMultiTableColumns({
|
||||
id: formJson.databaseId,
|
||||
tableNames: selectTableName.join(','),
|
||||
});
|
||||
for (const key in result) {
|
||||
const columnInfo = result[key];
|
||||
//如果已经写入过的表格 不再添加
|
||||
if (!tableInfo?.value.find((x) => x.name === key)) {
|
||||
const fields = columnInfo.map((field) => {
|
||||
const filedInfo: FieldInfo = {
|
||||
name: field.column,
|
||||
length: field.dataLength,
|
||||
type: JavaTypeConvertTsType(field.dataType),
|
||||
isPk: field.primaryKey,
|
||||
isNullable: field.nullable,
|
||||
};
|
||||
return filedInfo;
|
||||
});
|
||||
|
||||
tableInfo?.value.push({
|
||||
name: key,
|
||||
isMain: formJson!.tableConfigs!.find((x) => x.tableName === key)?.isMain as boolean,
|
||||
fields: fields,
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
emit('close');
|
||||
}
|
||||
|
||||
//上一步
|
||||
function handleStepPrev() {
|
||||
current.value--;
|
||||
}
|
||||
//下一步
|
||||
async function handleStepNext() {
|
||||
const isOk = await stepValidate[current.value]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
if (current.value === 0) {
|
||||
await getReleseInfo();
|
||||
}
|
||||
current.value++;
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
const isOk = await stepValidate[1]();
|
||||
if (!isOk) {
|
||||
return;
|
||||
}
|
||||
formReleaseConfig.listConfig = generatorConfig.listConfig;
|
||||
const params = {
|
||||
...toRaw(formReleaseConfig),
|
||||
id: releaseId.value,
|
||||
menuId: menuId.value,
|
||||
};
|
||||
if (isUpdate.value) {
|
||||
await updateFormRelease(params);
|
||||
} else {
|
||||
await addFormRelease(toRaw(formReleaseConfig));
|
||||
}
|
||||
closeModal();
|
||||
emit('success', isFormEdit.value);
|
||||
emit('close');
|
||||
}
|
||||
|
||||
const stepValidate = {
|
||||
//数据表配置 验证
|
||||
0: () => basicConfigStepRef.value.validateStep(),
|
||||
1: () => viewDesignStepRef.value.validateStep(),
|
||||
};
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.step-form-content {
|
||||
padding: 24px;
|
||||
background-color: @component-background;
|
||||
}
|
||||
|
||||
@keyframes rotation {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes rotationReverse {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-process) {
|
||||
.ant-steps-item-icon {
|
||||
border: 2px solid #fff;
|
||||
outline: 2px dashed #1890ff !important;
|
||||
line-height: 30px;
|
||||
animation: rotation 4s linear infinite;
|
||||
|
||||
.ant-steps-icon {
|
||||
display: inline-block;
|
||||
animation: rotationReverse 4s linear infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-form-form {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 400;
|
||||
|
||||
a {
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 16px;
|
||||
margin: 0 20px 0 -5px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-right: 10%;
|
||||
}
|
||||
|
||||
:deep(.ant-steps) {
|
||||
width: calc(100% - 900px);
|
||||
}
|
||||
|
||||
:deep(.ant-steps-item-container) {
|
||||
padding: 2px 0 2px 2px;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
|
||||
:deep(.ant-btn) {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-container {
|
||||
height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.step1 {
|
||||
padding: 14px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
147
src/views/form/release/index.vue
Normal file
147
src/views/form/release/index.vue
Normal file
@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<PageWrapper dense fixed-height contentFullHeight>
|
||||
<BasicTable @register="registerTable">
|
||||
<template #toolbar>
|
||||
<a-button type="primary" @click="handleCreate" v-auth="'form-release:add'">{{
|
||||
t('新增')
|
||||
}}</a-button>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<TableAction
|
||||
:actions="[
|
||||
{
|
||||
icon: 'clarity:note-edit-line',
|
||||
auth: 'form-release:edit',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
icon: 'ant-design:delete-outlined',
|
||||
auth: 'form-release:delete',
|
||||
color: 'error',
|
||||
popConfirm: {
|
||||
title: t('是否确认删除'),
|
||||
confirm: handleDelete.bind(null, record),
|
||||
},
|
||||
},
|
||||
]"
|
||||
/>
|
||||
</template>
|
||||
</BasicTable>
|
||||
|
||||
<ReleaseModal
|
||||
v-if="modalClose"
|
||||
@register="registerModal"
|
||||
@success="handleSuccess"
|
||||
@close="handleClose"
|
||||
/>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { BasicTable, useTable, TableAction, FormSchema, BasicColumn } from '/@/components/Table';
|
||||
import { getFormReleasePage, deleteFormRelease } from '/@/api/form/release';
|
||||
import { PageWrapper } from '/@/components/Page';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { useModal } from '/@/components/Modal';
|
||||
import ReleaseModal from './components/ReleaseModal.vue';
|
||||
const { t } = useI18n();
|
||||
const searchFormSchema: FormSchema[] = [
|
||||
{
|
||||
field: 'keyword',
|
||||
label: t('关键字'),
|
||||
component: 'Input',
|
||||
colProps: { span: 8 },
|
||||
componentProps: {
|
||||
placeholder: t('请输入关键字'),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const columns: BasicColumn[] = [
|
||||
{
|
||||
dataIndex: 'formName',
|
||||
title: t('表单名称'),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
dataIndex: 'menuName',
|
||||
title: t('菜单名称'),
|
||||
align: 'left',
|
||||
},
|
||||
{
|
||||
dataIndex: 'remark',
|
||||
title: t('备注'),
|
||||
align: 'left',
|
||||
},
|
||||
];
|
||||
const { notification } = useMessage();
|
||||
const modalClose = ref(true);
|
||||
defineEmits(['register']);
|
||||
const [registerModal, { openModal }] = useModal();
|
||||
const [registerTable, { reload }] = useTable({
|
||||
title: t('表单发布管理'),
|
||||
api: getFormReleasePage,
|
||||
rowKey: 'id',
|
||||
columns,
|
||||
formConfig: {
|
||||
rowProps: {
|
||||
gutter: 16,
|
||||
},
|
||||
schemas: searchFormSchema,
|
||||
showResetButton: false,
|
||||
},
|
||||
useSearchForm: true,
|
||||
showTableSetting: true,
|
||||
striped: false,
|
||||
actionColumn: {
|
||||
width: 80,
|
||||
title: t('操作'),
|
||||
dataIndex: 'action',
|
||||
slots: { customRender: 'action' },
|
||||
},
|
||||
tableSetting: {
|
||||
size: false,
|
||||
setting: false,
|
||||
},
|
||||
});
|
||||
|
||||
function handleCreate() {
|
||||
openModal(true, {
|
||||
title: t('新增表单发布'),
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
openModal(true, {
|
||||
id: record.id,
|
||||
isUpdate: true,
|
||||
title: t('编辑表单发布'),
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(record: Recordable) {
|
||||
deleteFormRelease([record.id]).then((_) => {
|
||||
reload();
|
||||
notification.success({
|
||||
message: t('提示'),
|
||||
description: t('删除成功'),
|
||||
}); //提示消息
|
||||
});
|
||||
}
|
||||
|
||||
function handleSuccess(isEdit) {
|
||||
notification.success({
|
||||
message: t('提示'),
|
||||
description: isEdit ? t('修改成功!') : t('发布成功!'),
|
||||
}); //提示消息
|
||||
reload();
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
modalClose.value = !modalClose.value;
|
||||
setTimeout(() => {
|
||||
modalClose.value = !modalClose.value;
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
222
src/views/form/template/components/FormModal.vue
Normal file
222
src/views/form/template/components/FormModal.vue
Normal file
@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<BasicModal
|
||||
v-if="formType === 'modal'"
|
||||
v-bind="$attrs"
|
||||
@register="registerModal"
|
||||
:title="getTitle"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleClose"
|
||||
:paddingRight="15"
|
||||
:bodyStyle="{ minHeight: '400px !important' }"
|
||||
>
|
||||
<SimpleForm ref="formRef" :formProps="formProps" :formModel="state.formModel" />
|
||||
</BasicModal>
|
||||
<BasicDrawer
|
||||
v-else
|
||||
showFooter
|
||||
v-bind="$attrs"
|
||||
@register="registerDrawer"
|
||||
:title="getTitle"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleClose"
|
||||
>
|
||||
<SimpleForm ref="formRef" :formProps="formProps" :formModel="state.formModel" />
|
||||
</BasicDrawer>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, reactive } from 'vue';
|
||||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||||
import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
|
||||
import { useMessage } from '/@/hooks/web/useMessage';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { usePermission } from '/@/hooks/web/usePermission';
|
||||
import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
|
||||
import { addFormExecute, getFormExecute, updateFormExecute } from '/@/api/form/execute';
|
||||
import { execute } from '/@/api/liteflow';
|
||||
import { apiConfigFunc } from '/@/utils/event/design';
|
||||
import { cloneDeep } from 'lodash-es';
|
||||
|
||||
const emit = defineEmits(['success', 'register']);
|
||||
const { notification } = useMessage();
|
||||
const { filterFormSchemaAuth } = usePermission();
|
||||
const formRef = ref();
|
||||
|
||||
const formProps = ref<any>({});
|
||||
const props = defineProps({
|
||||
formType: String,
|
||||
formWidth: Number,
|
||||
});
|
||||
let releaseId = ``;
|
||||
|
||||
const state = reactive({
|
||||
formModel: {},
|
||||
isUpdate: true,
|
||||
isView: false,
|
||||
isCopy: false,
|
||||
rowId: '',
|
||||
pkField: 'id',
|
||||
formEventConfig: [],
|
||||
key: 0,
|
||||
});
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||||
if (props.formType === 'modal') {
|
||||
handleInner(data, setModalProps);
|
||||
}
|
||||
});
|
||||
|
||||
const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
|
||||
if (props.formType === 'drawer') {
|
||||
handleInner(data, setDrawerProps);
|
||||
}
|
||||
});
|
||||
|
||||
const getTitle = computed(() =>
|
||||
state.isView ? t('查看') : state.isUpdate ? t('编辑') : state.isCopy ? '复制数据' : t('新增'),
|
||||
);
|
||||
|
||||
async function handleInner(data, setPropsData) {
|
||||
formProps.value = data.formProps;
|
||||
state.formEventConfig = data.formEventConfig;
|
||||
state.isView = !!data?.isView;
|
||||
state.isUpdate = !!data?.isUpdate;
|
||||
state.isCopy = !!data?.isCopy;
|
||||
|
||||
state.pkField = data.pkField;
|
||||
releaseId = data.releaseId;
|
||||
formProps.value.schemas = filterFormSchemaAuth(formProps.value.schemas!);
|
||||
|
||||
const viewformProps = cloneDeep(data.formProps);
|
||||
setDisabled(viewformProps.schemas);
|
||||
|
||||
formRef.value.setProps(state.isView ? viewformProps : data.formProps);
|
||||
|
||||
await formRef.value.setDefaultValue();
|
||||
if (!state.isUpdate && !state.isView && !state.isCopy) {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
|
||||
//初始化表单
|
||||
executeFormEvent(state.formEventConfig[0]);
|
||||
//加载表单
|
||||
executeFormEvent(state.formEventConfig[2]);
|
||||
|
||||
if (state.isUpdate || state.isView || state.isCopy) {
|
||||
state.rowId = data.id;
|
||||
const record = await getFormExecute({ releaseId, id: state.rowId });
|
||||
formRef.value.setFieldsValue(record);
|
||||
//获取表单数据
|
||||
executeFormEvent(state.formEventConfig[1]);
|
||||
}
|
||||
|
||||
setPropsData({
|
||||
destroyOnClose: true,
|
||||
maskClosable: false,
|
||||
showCancelBtn: !state.isView,
|
||||
showOkBtn: !state.isView,
|
||||
canFullscreen: true,
|
||||
width: props.formWidth,
|
||||
});
|
||||
}
|
||||
|
||||
function setDisabled(schemas) {
|
||||
const layoutComponents = ['tab', 'grid', 'card'];
|
||||
schemas?.map((info) => {
|
||||
if (layoutComponents.includes(info.type!)) {
|
||||
info.children?.map((childInfo) => {
|
||||
childInfo.list.map((com) => {
|
||||
if (layoutComponents.includes(com.type)) {
|
||||
setDisabled(childInfo.list);
|
||||
} else {
|
||||
com.dynamicDisabled = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
} else if (info.type == 'table-layout') {
|
||||
info.children?.map((childInfo) => {
|
||||
childInfo.list.map((com) => {
|
||||
com.children.map((el) => {
|
||||
if (layoutComponents.includes(el.type) || el.type == 'table-layout') {
|
||||
setDisabled(com.children);
|
||||
} else {
|
||||
el.dynamicDisabled = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else if (info.type == 'one-for-one') {
|
||||
setDisabled(info.componentProps.childSchemas);
|
||||
} else {
|
||||
info.dynamicDisabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//执行表单事件
|
||||
function executeFormEvent(formEventConfig) {
|
||||
if (!formEventConfig.length) return;
|
||||
formEventConfig.map((x) => {
|
||||
x.nodeInfo?.processEvent?.map(async (config) => {
|
||||
if (config.operateType === 'api') {
|
||||
await apiConfigFunc(config.operateConfig, true, state.formModel);
|
||||
} else if (config.operateType === 'liteflow') {
|
||||
await execute(config.operateConfig, state.formModel);
|
||||
} else if (config.operateType === 'js') {
|
||||
const event = new Function('schema', 'formModel', 'formActionType', config.operateConfig);
|
||||
event(formProps.value.schemas, state.formModel, formRef.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
const values = await formRef.value?.validate();
|
||||
//添加隐藏组件
|
||||
if (formProps.value.hiddenComponent?.length) {
|
||||
formProps.value.hiddenComponent.forEach((component) => {
|
||||
values[component.bindField] = component.value;
|
||||
});
|
||||
}
|
||||
props.formType === 'modal'
|
||||
? setModalProps({ confirmLoading: true })
|
||||
: setDrawerProps({ confirmLoading: false });
|
||||
|
||||
// TODO custom api
|
||||
if (!state.isUpdate) {
|
||||
//false 新增
|
||||
await addFormExecute({ releaseId, formData: values });
|
||||
|
||||
notification.success({
|
||||
message: t('提示'),
|
||||
description: t('新增成功!'),
|
||||
}); //提示消息
|
||||
} else {
|
||||
values[state.pkField] = state.rowId;
|
||||
await updateFormExecute({ releaseId, formData: values });
|
||||
|
||||
notification.success({
|
||||
message: t('提示'),
|
||||
description: t('修改成功!'),
|
||||
}); //提示消息
|
||||
}
|
||||
|
||||
//提交表单事件
|
||||
executeFormEvent(state.formEventConfig[3]);
|
||||
props.formType === 'modal' ? closeModal() : closeDrawer();
|
||||
formRef.value.resetFields();
|
||||
emit('success');
|
||||
} catch (error) {
|
||||
} finally {
|
||||
props.formType === 'modal'
|
||||
? setModalProps({ confirmLoading: false })
|
||||
: setDrawerProps({ confirmLoading: false });
|
||||
}
|
||||
}
|
||||
|
||||
function handleClose() {
|
||||
formRef.value.resetFields();
|
||||
}
|
||||
</script>
|
||||
1062
src/views/form/template/index.vue
Normal file
1062
src/views/form/template/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user