467 lines
12 KiB
Vue
467 lines
12 KiB
Vue
<template>
|
||
<BasicModal
|
||
v-bind="$attrs"
|
||
@register="registerModal"
|
||
title="生成代码"
|
||
:width="800"
|
||
@ok="handleSuccess"
|
||
>
|
||
<BasicForm @register="registerForm" />
|
||
</BasicModal>
|
||
</template>
|
||
<script lang="ts" setup>
|
||
import { ref, computed, reactive } from 'vue';
|
||
import { BasicModal, useModalInner } from '/@/components/Modal';
|
||
import { BasicForm, useForm, FormSchema, FormProps } from '/@/components/Form/index';
|
||
import { getDatabaselinkMultiTableColumns } from '/@/api/system/databaselink';
|
||
import { getAuthList } from '/@/api/system/authorize';
|
||
import { useUserStore } from '/@/store/modules/user';
|
||
import { GeneratorModel } from '/@/api/system/generator/model';
|
||
import { ComponentOptionModel } from '/@/model/generator/codeGenerator';
|
||
import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
|
||
import { debounce, random, cloneDeep } from 'lodash-es';
|
||
import { buildUUID } from '/@/utils/uuid';
|
||
import { JavaTypeConvertTsType, buildOption } from '/@/utils/helper/designHelper';
|
||
import { buildCode } from '/@/utils/helper/generatorHelper';
|
||
|
||
import { useI18n } from '/@/hooks/web/useI18n';
|
||
|
||
const { t } = useI18n();
|
||
const userStore = useUserStore();
|
||
|
||
const dataAuthHelpMessage = `
|
||
1.启用数据权限会判断主表是否包含RuleUserlD字段如果存在,则不进行表结构修改,如果不存在,则会对主表进行字段添加。
|
||
2.RuleUserlD主要用来控制每一条记录的权限所属人新增时,默认将当前登录认作为权限所属人。
|
||
3.在表单设计中会添加“批量设置权限所属人”功能启用后,拥有该按钮权限的人员可以设置每一条记录的权限所属人。
|
||
`;
|
||
|
||
const dataAuthPlaceholder = computed(() => {
|
||
return generatorConfig!.outputConfig!.isDataAuth
|
||
? t('请选择已有通用数据权限')
|
||
: t('请先启用数据权限');
|
||
});
|
||
|
||
const inputComponentInfo: ComponentOptionModel = {
|
||
label: '单行文本',
|
||
typeName: '单行文本',
|
||
type: 'input',
|
||
options: {
|
||
width: '100%',
|
||
span: '',
|
||
defaultValue: '',
|
||
placeholder: '请输入单行文本',
|
||
maxlength: '',
|
||
prefix: '',
|
||
suffix: '',
|
||
addonBefore: '',
|
||
addonAfter: '',
|
||
disabled: false,
|
||
allowClear: false,
|
||
showLabel: true,
|
||
required: false,
|
||
rules: [],
|
||
events: {},
|
||
},
|
||
key: '',
|
||
rules: [],
|
||
isSubFormChild: false,
|
||
isSingleFormChild: false,
|
||
bindTable: '',
|
||
bindField: '',
|
||
};
|
||
|
||
const numberComponentInfo: ComponentOptionModel = {
|
||
label: '计数组件',
|
||
typeName: '计数组件',
|
||
type: 'number',
|
||
options: {
|
||
width: '100%',
|
||
span: '',
|
||
defaultValue: 0,
|
||
min: 0,
|
||
max: 100,
|
||
step: 1,
|
||
maxlength: '',
|
||
disabled: false,
|
||
showLabel: true,
|
||
controls: true,
|
||
required: false,
|
||
subTotal: false,
|
||
rules: [],
|
||
events: {},
|
||
},
|
||
key: '',
|
||
rules: [],
|
||
isSubFormChild: false,
|
||
isSingleFormChild: false,
|
||
bindTable: '',
|
||
bindField: '',
|
||
};
|
||
|
||
const timeComponentInfo: ComponentOptionModel = {
|
||
label: '时间选择',
|
||
typeName: '时间选择',
|
||
type: 'time',
|
||
options: {
|
||
span: '',
|
||
defaultValue: '',
|
||
width: '100%',
|
||
placeholder: '请选择时间选择',
|
||
format: 'HH:mm:ss',
|
||
showLabel: true,
|
||
allowClear: true,
|
||
disabled: false,
|
||
required: false,
|
||
rules: [],
|
||
events: {},
|
||
},
|
||
key: '',
|
||
rules: [],
|
||
isSubFormChild: false,
|
||
isSingleFormChild: false,
|
||
bindTable: '',
|
||
bindField: '',
|
||
};
|
||
|
||
const dateComponentInfo: ComponentOptionModel = {
|
||
label: '日期选择',
|
||
typeName: '日期选择',
|
||
type: 'date',
|
||
options: {
|
||
span: '',
|
||
defaultValue: '',
|
||
width: '100%',
|
||
placeholder: '请选择日期选择',
|
||
format: 'YYYY-MM-DD HH:mm:ss',
|
||
showLabel: true,
|
||
allowClear: true,
|
||
disabled: false,
|
||
required: false,
|
||
rules: [],
|
||
events: {},
|
||
},
|
||
key: '',
|
||
rules: [],
|
||
isSubFormChild: false,
|
||
isSingleFormChild: false,
|
||
bindTable: '',
|
||
bindField: '',
|
||
};
|
||
const outputValue = ref('');
|
||
const columnsInfo = ref<any>({});
|
||
const codeList = ref<GeneratorModel[]>([]);
|
||
|
||
const emit = defineEmits(['success']);
|
||
|
||
let generatorConfig = reactive<GeneratorModel>({
|
||
name: '',
|
||
categoryId: '1697809616871182337',
|
||
databaseId: null, //数据库id
|
||
listConfig: {
|
||
isLeftMenu: false,
|
||
queryConfigs: [],
|
||
leftMenuConfig: {
|
||
datasourceType: 'static',
|
||
listFieldName: undefined,
|
||
apiConfig: {},
|
||
dictionaryItemId: undefined,
|
||
menuName: '',
|
||
parentIcon: '',
|
||
childIcon: '',
|
||
staticData: [],
|
||
},
|
||
columnConfigs: [],
|
||
buttonConfigs: [
|
||
{
|
||
isUse: true,
|
||
name: '刷新',
|
||
code: 'refresh',
|
||
icon: 'ant-design:reload-outlined',
|
||
isDefault: true,
|
||
},
|
||
{
|
||
isUse: true,
|
||
name: '查看',
|
||
code: 'view',
|
||
icon: 'ant-design:eye-outlined',
|
||
isDefault: true,
|
||
},
|
||
{
|
||
isUse: true,
|
||
name: '新增',
|
||
code: 'add',
|
||
icon: 'ant-design:plus-outlined',
|
||
isDefault: true,
|
||
},
|
||
{
|
||
isUse: true,
|
||
name: '编辑',
|
||
code: 'edit',
|
||
icon: 'ant-design:form-outlined',
|
||
isDefault: true,
|
||
},
|
||
{
|
||
isUse: true,
|
||
name: '删除',
|
||
code: 'delete',
|
||
icon: 'ant-design:delete-outlined',
|
||
isDefault: true,
|
||
},
|
||
],
|
||
defaultOrder: true,
|
||
isPage: true,
|
||
},
|
||
tableConfigs: [],
|
||
formJson: {
|
||
list: [],
|
||
config: {
|
||
formType: 'modal',
|
||
size: 'default',
|
||
layout: 'horizontal',
|
||
labelAlign: 'right',
|
||
labelCol: {
|
||
span: 3,
|
||
offset: 0,
|
||
},
|
||
formWidth: 800,
|
||
},
|
||
hiddenComponent: [],
|
||
},
|
||
outputConfig: {
|
||
creator: userStore.getUserInfo.name,
|
||
isMenu: true,
|
||
type: 0,
|
||
},
|
||
formEventConfig: {} as FormEventColumnConfig,
|
||
frontCode: {
|
||
listCode: '',
|
||
formCode: '',
|
||
apiCode: '',
|
||
modelCode: '',
|
||
configJsonCode: '',
|
||
workflowPermissionCode: '', //工作流权限配置
|
||
simpleFormCode: '', //simpleForm页面
|
||
},
|
||
});
|
||
const schemas: FormSchema[] = [
|
||
{
|
||
field: 'className',
|
||
label: t('功能名称'),
|
||
component: 'Input',
|
||
rules: [
|
||
{
|
||
required: true,
|
||
validator: (_, value) => {
|
||
if (value === '') {
|
||
return Promise.reject('请输入功能名称');
|
||
} else if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(value)) {
|
||
return Promise.reject(t('功能名称只能是数字和字母组成,必须以英文字母开头'));
|
||
} else {
|
||
return Promise.resolve();
|
||
}
|
||
},
|
||
trigger: 'blur',
|
||
},
|
||
],
|
||
colProps: { span: 24 },
|
||
componentProps: {
|
||
placeholder: '请填写功能名称',
|
||
},
|
||
},
|
||
{
|
||
field: 'comment',
|
||
label: t('功能描述'),
|
||
required: true,
|
||
component: 'Input',
|
||
colProps: { span: 24 },
|
||
componentProps: {
|
||
placeholder: '请填写功能描述',
|
||
},
|
||
},
|
||
{
|
||
field: 'outputArea',
|
||
label: t('功能模块'),
|
||
component: 'DicSelect',
|
||
required: true,
|
||
componentProps: {
|
||
placeholder: t('请选择功能模块'),
|
||
itemId: '1419276800524423333',
|
||
getPopupContainer: () => document.body,
|
||
onChange: debounce((_, obj) => {
|
||
if (obj) {
|
||
outputValue.value = obj.value;
|
||
}
|
||
}, 100),
|
||
},
|
||
colProps: { span: 24 },
|
||
},
|
||
{
|
||
field: 'remarks',
|
||
label: t('备注'),
|
||
component: 'Input',
|
||
colProps: { span: 24 },
|
||
componentProps: {
|
||
placeholder: t('请填写备注'),
|
||
},
|
||
},
|
||
{
|
||
field: 'isDataAuth',
|
||
label: t('数据权限'),
|
||
component: 'Switch',
|
||
colProps: { span: 24 },
|
||
helpMessage: dataAuthHelpMessage,
|
||
helpComponentProps: { maxWidth: '400px' },
|
||
componentProps: {
|
||
checkedValue: true,
|
||
unCheckedValue: false,
|
||
},
|
||
},
|
||
{
|
||
field: 'dataAuthList',
|
||
label: t('权限选择'),
|
||
component: 'ApiSelect',
|
||
colProps: { span: 24 },
|
||
componentProps: {
|
||
mode: 'multiple',
|
||
placeholder: dataAuthPlaceholder,
|
||
api: getAuthList,
|
||
labelField: 'name',
|
||
valueField: 'id',
|
||
getPopupContainer: () => document.body,
|
||
},
|
||
dynamicDisabled: ({ values }) => {
|
||
return !values.isDataAuth;
|
||
},
|
||
},
|
||
];
|
||
const [registerForm, { validate }] = useForm({
|
||
labelWidth: 100,
|
||
schemas: schemas,
|
||
showActionButtonGroup: false,
|
||
actionColOptions: {
|
||
span: 23,
|
||
},
|
||
});
|
||
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
|
||
setModalProps({
|
||
confirmLoading: false,
|
||
destroyOnClose: true,
|
||
});
|
||
|
||
columnsInfo.value = await getDatabaselinkMultiTableColumns({
|
||
id: data.databaseId,
|
||
tableNames: data.tableName.toString(),
|
||
});
|
||
for (let key in columnsInfo.value) {
|
||
const generatorConfigInfo = cloneDeep(generatorConfig);
|
||
if (!generatorConfigInfo.databaseId) generatorConfigInfo.databaseId = data.databaseId;
|
||
|
||
const col = columnsInfo.value[key].find((x) => x.primaryKey);
|
||
generatorConfigInfo.tableConfigs = [
|
||
{
|
||
isMain: true,
|
||
order: 1,
|
||
pkField: col.column,
|
||
pkType: col.dataType,
|
||
tableName: key,
|
||
},
|
||
];
|
||
generatorConfigInfo.name = key;
|
||
columnsInfo.value[key].forEach((item) => {
|
||
let info;
|
||
switch (item.dataType) {
|
||
case 'LocalTime':
|
||
info = timeComponentInfo;
|
||
break;
|
||
case 'LocalDateTime':
|
||
info = dateComponentInfo;
|
||
break;
|
||
case 'Integer':
|
||
info = numberComponentInfo;
|
||
break;
|
||
default:
|
||
info = inputComponentInfo;
|
||
break;
|
||
}
|
||
|
||
const componentInfo = cloneDeep(info);
|
||
componentInfo.key = buildUUID().replaceAll('-', '');
|
||
componentInfo.bindTable = key;
|
||
componentInfo.bindField = item.column;
|
||
componentInfo.label = item.column;
|
||
generatorConfigInfo.formJson.list.push(componentInfo);
|
||
|
||
generatorConfigInfo.listConfig.queryConfigs.push({
|
||
fieldName: item.column,
|
||
isDate: ['LocalTime', 'LocalDateTime'].includes(item.dataType),
|
||
width: 8,
|
||
});
|
||
console.log('queryConfigsqueryConfigs', generatorConfigInfo.listConfig.queryConfigs);
|
||
generatorConfigInfo.listConfig.columnConfigs.push({
|
||
key: componentInfo.key,
|
||
autoWidth: true,
|
||
columnName: item.column,
|
||
componentType: 'input',
|
||
isNumber: false,
|
||
isTotal: false,
|
||
label: item.column,
|
||
});
|
||
});
|
||
|
||
const fieldsInfo = columnsInfo.value[key].map((field) => {
|
||
return {
|
||
name: field.column,
|
||
length: field.dataLength,
|
||
type: JavaTypeConvertTsType(field.dataType),
|
||
isPk: field.primaryKey,
|
||
isNullable: field.nullable,
|
||
};
|
||
});
|
||
const tableInfo = [
|
||
{
|
||
name: key,
|
||
fields: fieldsInfo,
|
||
isMain: true,
|
||
},
|
||
];
|
||
generatorConfigInfo.frontCode = buildCode(
|
||
generatorConfigInfo,
|
||
tableInfo,
|
||
buildOption(generatorConfigInfo.formJson) as FormProps,
|
||
);
|
||
|
||
codeList.value.push(generatorConfigInfo);
|
||
}
|
||
});
|
||
|
||
const handleSuccess = async () => {
|
||
const data = await validate();
|
||
codeList.value.map(async (item) => {
|
||
item.outputConfig = { ...item.outputConfig, ...data };
|
||
item.outputConfig.className = item.outputConfig.className! + random(1000, 9999);
|
||
item.outputConfig.outputValue = outputValue.value;
|
||
|
||
const fieldsInfo = columnsInfo.value[item.name!].map((field) => {
|
||
return {
|
||
name: field.column,
|
||
length: field.dataLength,
|
||
type: JavaTypeConvertTsType(field.dataType),
|
||
isPk: field.primaryKey,
|
||
isNullable: field.nullable,
|
||
};
|
||
});
|
||
const tableInfo = [
|
||
{
|
||
name: item.name!,
|
||
fields: fieldsInfo,
|
||
isMain: true,
|
||
},
|
||
];
|
||
item.frontCode = buildCode(item, tableInfo, buildOption(item.formJson) as FormProps);
|
||
|
||
closeModal();
|
||
});
|
||
emit('success', codeList.value);
|
||
};
|
||
</script>
|