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>
|