feat: 新增代码生成管理接口及视图模块

pull/48/head
chenminjie 2024-11-26 06:09:59 +08:00
parent 23bcf4f61b
commit 1fa93dd5db
5 changed files with 773 additions and 0 deletions

View File

@ -0,0 +1,312 @@
import { type PageParam, requestClient } from '#/api/request';
export namespace CodegenApi {
/**
* Response VO
*/
export interface CodegenColumnRespVO {
/** 编号 */
id: number;
/** 表编号 */
tableId: number;
/** 字段名 */
columnName: string;
/** 字段类型 */
dataType: string;
/** 字段描述 */
columnComment: string;
/** 是否允许为空 */
nullable: boolean;
/** 是否主键 */
primaryKey: boolean;
/** 排序 */
ordinalPosition: number;
/** Java 属性类型 */
javaType: string;
/** Java 属性名 */
javaField: string;
/** 字典类型 */
dictType?: string;
/** 数据示例 */
example?: string;
/** 是否为 Create 创建操作的字段 */
createOperation: boolean;
/** 是否为 Update 更新操作的字段 */
updateOperation: boolean;
/** 是否为 List 查询操作的字段 */
listOperation: boolean;
/** List 查询操作的条件类型 */
listOperationCondition: string;
/** 是否为 List 查询操作的返回字段 */
listOperationResult: boolean;
/** 显示类型 */
htmlType: string;
/** 创建时间 */
createTime: string; // 假设为 ISO 字符串格式的 LocalDateTime
}
/**
* / Request VO
*/
export interface CodegenColumnSaveReqVO {
/** 编号 */
id: number;
/** 表编号 */
tableId: number;
/** 字段名 */
columnName: string;
/** 字段类型 */
dataType: string;
/** 字段描述 */
columnComment: string;
/** 是否允许为空 */
nullable: boolean;
/** 是否主键 */
primaryKey: boolean;
/** 排序 */
ordinalPosition: number;
/** Java 属性类型 */
javaType: string;
/** Java 属性名 */
javaField: string;
/** 字典类型 */
dictType?: string;
/** 数据示例 */
example?: string;
/** 是否为 Create 创建操作的字段 */
createOperation: boolean;
/** 是否为 Update 更新操作的字段 */
updateOperation: boolean;
/** 是否为 List 查询操作的字段 */
listOperation: boolean;
/** List 查询操作的条件类型 */
listOperationCondition: string;
/** 是否为 List 查询操作的返回字段 */
listOperationResult: boolean;
/** 显示类型 */
htmlType: string;
}
/**
* Request VO
*/
export interface CodegenTablePageReqVO {
/** 表名称,模糊匹配 */
tableName?: string;
/** 表描述,模糊匹配 */
tableComment?: string;
/** 实体,模糊匹配 */
className?: string;
/** 创建时间 */
createTime?: [string, string]; // 假设为 ISO 字符串格式的 LocalDateTime
}
/**
* Response VO
*/
export interface CodegenTableRespVO {
/** 编号 */
id: number;
/** 生成场景 */
scene: number;
/** 表名称 */
tableName: string;
/** 表描述 */
tableComment: string;
/** 备注 */
remark?: string;
/** 模块名 */
moduleName: string;
/** 业务名 */
businessName: string;
/** 类名称 */
className: string;
/** 类描述 */
classComment: string;
/** 作者 */
author: string;
/** 模板类型 */
templateType: number;
/** 前端类型 */
frontType: number;
/** 父菜单编号 */
parentMenuId?: number;
/** 主表的编号 */
masterTableId?: number;
/** 子表关联主表的字段编号 */
subJoinColumnId?: number;
/** 主表与子表是否一对多 */
subJoinMany?: boolean;
/** 树表的父字段编号 */
treeParentColumnId?: number;
/** 树表的名字字段编号 */
treeNameColumnId?: number;
/** 主键编号 */
dataSourceConfigId: number;
/** 创建时间 */
createTime: string; // 假设为 ISO 字符串格式的 LocalDateTime
/** 更新时间 */
updateTime: string; // 假设为 ISO 字符串格式的 LocalDateTime
}
/**
* / Response VO
*/
export interface CodegenTableSaveReqVO {
/** 编号 */
id: number;
/** 生成场景 */
scene: number;
/** 表名称 */
tableName: string;
/** 表描述 */
tableComment: string;
/** 备注 */
remark?: string;
/** 模块名 */
moduleName: string;
/** 业务名 */
businessName: string;
/** 类名称 */
className: string;
/** 类描述 */
classComment: string;
/** 作者 */
author: string;
/** 模板类型 */
templateType: number;
/** 前端类型 */
frontType: number;
/** 父菜单编号 */
parentMenuId?: number;
/** 主表的编号 */
masterTableId?: number;
/** 子表关联主表的字段编号 */
subJoinColumnId?: number;
/** 主表与子表是否一对多 */
subJoinMany?: boolean;
/** 树表的父字段编号 */
treeParentColumnId?: number;
/** 树表的名字字段编号 */
treeNameColumnId?: number;
}
/**
* Response VO
*/
export interface DatabaseTableRespVO {
/** 表名称 */
name: string;
/** 表描述 */
comment: string;
}
/**
* Request VO
*/
export interface CodegenCreateListReqVO {
/** 数据源配置的编号 */
dataSourceConfigId: number;
/** 表名数组 */
tableNames: string[];
}
/**
* Response VO
*/
export interface CodegenDetailRespVO {
/** 表定义 */
table: CodegenTableRespVO;
/** 字段定义 */
columns: CodegenColumnRespVO[];
}
/**
* Response VO
*/
export interface CodegenPreviewRespVO {
/** 文件路径 */
filePath: string;
/** 代码 */
code: string;
}
/**
* Request VO
*/
export interface CodegenUpdateReqVO {
/** 表定义 */
table: CodegenTableSaveReqVO;
/** 字段定义 */
columns: CodegenColumnSaveReqVO[];
}
}
// 查询列表代码生成表定义
export const getCodegenTableList = (dataSourceConfigId: number) => {
return requestClient.get<CodegenApi.CodegenTableRespVO[]>(
`/infra/codegen/table/list?dataSourceConfigId=${dataSourceConfigId}`,
);
};
// 查询列表代码生成表定义
export const getCodegenTablePage = (params: PageParam) => {
return requestClient.get<CodegenApi.CodegenTableRespVO[]>(
'/infra/codegen/table/page',
{ params },
);
};
// 查询详情代码生成表定义
export const getCodegenTable = (id: number) => {
return requestClient.get<CodegenApi.CodegenDetailRespVO>(
`/infra/codegen/detail?tableId=${id}`,
);
};
// 新增代码生成表定义
export const createCodegenTable = (data: CodegenApi.CodegenCreateListReqVO) => {
return requestClient.post('/infra/codegen/create', data);
};
// 修改代码生成表定义
export const updateCodegenTable = (data: CodegenApi.CodegenUpdateReqVO) => {
return requestClient.put('/infra/codegen/update', data);
};
// 基于数据库的表结构,同步数据库的表和字段定义
export const syncCodegenFromDB = (id: number) => {
return requestClient.put(`/infra/codegen/sync-from-db?tableId=${id}`);
};
// 预览生成代码
export const previewCodegen = (id: number) => {
return requestClient.get(`/infra/codegen/preview?tableId=${id}`);
};
// 下载生成代码
export const downloadCodegen = (id: number) => {
return requestClient.download(`/infra/codegen/download?tableId=${id}`);
};
// 获得表定义
export const getSchemaTableList = (params: {
comment?: string;
dataSourceConfigId: number;
name?: string;
}) => {
return requestClient.get<CodegenApi.DatabaseTableRespVO[]>(
'/infra/codegen/db/table/list',
{ params },
);
};
// 基于数据库的表结构,创建代码生成器的表定义
export const createCodegenList = (data: CodegenApi.CodegenCreateListReqVO) => {
return requestClient.post('/infra/codegen/create-list', data);
};
// 删除代码生成表定义
export const deleteCodegenTable = (id: number) => {
return requestClient.delete(`/infra/codegen/delete?tableId=${id}`);
};

View File

@ -0,0 +1,51 @@
import { requestClient } from '#/api/request';
export namespace DataSourceConfigApi {
export interface DataSourceConfigRespVO {
id: number;
name: string;
url: string;
username: string;
createTime?: Date;
}
export interface DataSourceConfigSaveReqVO {
id?: number;
name: string;
url: string;
username: string;
password: string;
}
}
// 新增数据源配置
export const createDataSourceConfig = (
data: DataSourceConfigApi.DataSourceConfigSaveReqVO,
) => {
return requestClient.post('/infra/data-source-config/create', data);
};
// 修改数据源配置
export const updateDataSourceConfig = (
data: DataSourceConfigApi.DataSourceConfigSaveReqVO,
) => {
return requestClient.put('/infra/data-source-config/update', data);
};
// 删除数据源配置
export const deleteDataSourceConfig = (id: number) => {
return requestClient.delete(`/infra/data-source-config/delete?id=${id}`);
};
// 查询数据源配置详情
export const getDataSourceConfig = (id: number) => {
return requestClient.get<DataSourceConfigApi.DataSourceConfigRespVO>(
`/infra/data-source-config/get?id=${id}`,
);
};
// 查询数据源配置列表
export const getDataSourceConfigList = () => {
return requestClient.get<DataSourceConfigApi.DataSourceConfigRespVO[]>(
'/infra/data-source-config/list',
);
};

View File

@ -0,0 +1,98 @@
import type { VbenFormProps } from '@vben/common-ui';
import type { VxeGridProps } from '#/adapter/vxe-table';
import type { CodegenApi } from '#/api/infra/codegen';
export namespace CodegenDefaultData {
/**
*
*/
export const tableColumns: VxeGridProps<CodegenApi.CodegenTableRespVO>['columns'] =
[
{
type: 'checkbox',
width: 50,
},
{
type: 'seq',
width: 50,
},
{ field: 'id', title: '编号', width: 100 },
{ field: 'tableName', title: '表名' },
{ field: 'tableComment', title: '表描述' },
{ field: 'className', title: '实体类名' },
{ field: 'createTime', title: '创建时间', formatter: 'formatDateTime' },
{ field: 'updateTime', title: '更新时间', formatter: 'formatDateTime' },
{
title: '操作',
width: 'auto',
fixed: 'right',
slots: { default: 'action' },
},
];
/**
*
*/
export const formSchema: VbenFormProps['schema'] = [
{
label: '表名称',
fieldName: 'tableName',
component: 'Input',
},
{
label: '表描述',
fieldName: 'tableComment',
component: 'Input',
},
{
label: '创建时间',
fieldName: 'createTime',
component: 'DatePicker',
componentProps: {
type: 'daterange',
format: 'YYYY-MM-DD',
valueFormat: 'YYYY-MM-DD',
},
},
];
}
//* ****************************** ImportTableModal.vue *******************************//
export namespace CodegenImportTableModalData {
/**
*
*/
export const tableColumns: VxeGridProps<CodegenApi.DatabaseTableRespVO>['columns'] =
[
{ type: 'checkbox', width: 50 },
{ type: 'seq', title: '序号', width: 50 },
{ field: 'name', title: '表名' },
{ field: 'comment', title: '表描述' },
];
/**
*
*/
export const formSchema: VbenFormProps['schema'] = [
{
label: '数据源',
fieldName: 'dataSourceConfigId',
component: 'Select',
componentProps: {
allowClear: true,
placeholder: '请选择数据源',
},
},
{
label: '表名称',
fieldName: 'name',
component: 'Input',
},
{
label: '表描述',
fieldName: 'comment',
component: 'Input',
},
];
}

View File

@ -0,0 +1,118 @@
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { useVbenModal, type VbenFormProps } from '@vben/common-ui';
import {
useVbenVxeGrid,
type VxeGridListeners,
type VxeGridProps,
} from '@vben/plugins/vxe-table';
import { getSchemaTableList } from '#/api/infra/codegen';
import {
type DataSourceConfigApi,
getDataSourceConfigList,
} from '#/api/infra/data-source-config';
import { CodegenImportTableModalData } from '../codegen.data';
// checked
const checkedStatus = ref<boolean>(false);
const dataSourceConfigList =
ref<DataSourceConfigApi.DataSourceConfigRespVO[]>();
/**
* 表格查询表单配置
*/
const formOptions = reactive<any>({
//
collapsed: false,
schema: CodegenImportTableModalData.formSchema,
//
showCollapseButton: true,
submitButtonOptions: {
content: '查询',
},
//
submitOnEnter: false,
} as VbenFormProps);
/**
* 表格配置
*/
const gridOptions = reactive<any>({
columns: CodegenImportTableModalData.tableColumns,
toolbarConfig: {
enabled: false,
},
height: 'auto',
proxyConfig: {
autoLoad: false,
ajax: {
query: async (_, values) => {
return await getSchemaTableList(values);
},
},
},
pagerConfig: {
enabled: false,
},
} as VxeGridProps);
const gridEvents = reactive<any>({
checkboxChange: (params) => {
const { checked } = params;
checkedStatus.value = checked;
},
checkboxAll: (params) => {
const { checked } = params;
checkedStatus.value = checked;
},
} as VxeGridListeners);
// 使
const [Grid, gridApi] = useVbenVxeGrid(
reactive({
formOptions,
gridOptions,
gridEvents,
}),
);
const [Modal] = useVbenModal({
class: 'w-[800px] h-[800px]',
onOpenChange: async (isOpen) => {
if (isOpen) {
//
dataSourceConfigList.value = await getDataSourceConfigList();
//
gridApi.formApi.updateSchema([
{
fieldName: 'dataSourceConfigId',
componentProps: {
options: dataSourceConfigList.value?.map((item) => ({
label: item.name,
value: item.id,
})),
},
},
]);
//
gridApi.formApi.setFieldValue(
'dataSourceConfigId',
dataSourceConfigList.value?.[0]?.id,
);
//
gridApi.reload(await gridApi.formApi.getValues());
}
},
});
</script>
<template>
<Modal>
<Grid />
</Modal>
</template>

View File

@ -0,0 +1,194 @@
<script lang="ts" setup>
import { defineAsyncComponent, reactive, ref } from 'vue';
import { Page, useVbenModal, type VbenFormProps } from '@vben/common-ui';
import { Button } from 'ant-design-vue';
import {
useVbenVxeGrid,
type VxeGridListeners,
type VxeGridProps,
} from '#/adapter/vxe-table';
import { type CodegenApi, getCodegenTablePage } from '#/api/infra/codegen';
import { CodegenDefaultData } from './codegen.data';
// 使
const [ImportTableModal, importTableModalApi] = useVbenModal({
connectedComponent: defineAsyncComponent(
() => import('./components/import-table-modal.vue'),
),
});
// checked
const checkedStatus = ref<boolean>(false);
/**
* 查看详情
*/
const handleView = (_row: CodegenApi.CodegenTableRespVO) => {
// console.log('', row);
};
/**
* 编辑
*/
const handleEdit = (_row: CodegenApi.CodegenTableRespVO) => {
// console.log('', row);
};
/**
* 删除
*/
const handleDelete = (_row: CodegenApi.CodegenTableRespVO) => {
// console.log('', row);
};
/**
* 批量删除
*/
const handleBatchDelete = (_rows: CodegenApi.CodegenTableRespVO[]) => {
// console.log('', rows);
};
/**
* 导入表
*/
const handleImportTable = () => {
// console.log('', importTableModalApi);
importTableModalApi.open();
};
/**
* 同步
*/
const handleSync = (_row: CodegenApi.CodegenTableRespVO) => {
// console.log('', row);
};
/**
* 批量同步
*/
const handleBatchSync = (_rows: CodegenApi.CodegenTableRespVO[]) => {
// console.log('', rows);
};
/**
* 生成代码
*/
const handleGenerateCode = (_row: CodegenApi.CodegenTableRespVO) => {
// console.log('', row);
};
/**
* 批量生成代码
*/
const handleBatchGenerateCode = (_rows: CodegenApi.CodegenTableRespVO[]) => {
// console.log('', rows);
};
/**
* 表格查询表单配置
*/
const formOptions = reactive<any>({
//
collapsed: false,
schema: CodegenDefaultData.formSchema,
//
showCollapseButton: true,
submitButtonOptions: {
content: '查询',
},
//
submitOnEnter: false,
} as VbenFormProps);
/**
* 表格配置
*/
const gridOptions = reactive<any>({
columns: CodegenDefaultData.tableColumns,
toolbarConfig: {
slots: {
buttons: 'toolbar_buttons',
},
},
proxyConfig: {
ajax: {
query: async ({ page }, params) => {
const data = await getCodegenTablePage({
pageNo: page.currentPage,
pageSize: page.pageSize,
...params,
});
return data;
},
},
},
} as VxeGridProps);
const gridEvents = reactive<any>({
checkboxChange: (params) => {
const { checked } = params;
checkedStatus.value = checked;
},
checkboxAll: (params) => {
const { checked } = params;
checkedStatus.value = checked;
},
} as VxeGridListeners);
// 使
const [Grid] = useVbenVxeGrid({
formOptions,
gridOptions,
gridEvents,
});
</script>
<template>
<Page auto-content-height>
<Grid>
<template #toolbar_buttons="{ $grid }">
<div class="flex items-center gap-2">
<Button type="primary" @click="handleImportTable"></Button>
<Button
:disabled="!checkedStatus"
type="primary"
@click="handleBatchSync($grid.getCheckboxRecords())"
>
批量同步
</Button>
<Button
:disabled="!checkedStatus"
type="primary"
@click="handleBatchGenerateCode($grid.getCheckboxRecords())"
>
批量生成
</Button>
<Button
:disabled="!checkedStatus"
danger
type="primary"
@click="handleBatchDelete($grid.getCheckboxRecords())"
>
批量删除
</Button>
</div>
</template>
<template #action="{ row }">
<div class="flex w-fit items-center justify-around">
<Button type="link" @click="handleView(row)"></Button>
<Button type="link" @click="handleEdit(row)"></Button>
<Button type="link" @click="handleSync(row)"></Button>
<Button type="link" @click="handleGenerateCode(row)">
生成代码
</Button>
<Button danger type="link" @click="handleDelete(row)"></Button>
</div>
</template>
</Grid>
<ImportTableModal />
</Page>
</template>