15 KiB
15 KiB
低代码生成平台 - 前端接口对接文档
📋 更新概述
本次后端更新新增了数据库选择功能,支持按数据库筛选表列表。前端需要相应修改以支持以下功能:
- 新增接口:获取数据库列表
- 增强接口:表列表接口支持按数据库筛选
- 返回数据变更:表列表返回数据新增
dataBase字段
🆕 1. 新增接口:获取数据库列表
接口信息
- 请求路径:
GET /api/CodeGeneration/databases - 请求方法:
GET - 是否需要认证:是
- 描述:获取所有可用的数据库列表,用于前端下拉框选择
请求参数
无
响应示例
[
{
"key": "Admin",
"displayName": "主数据库"
},
{
"key": "MiaoYuChat",
"displayName": "喵语聊天"
},
{
"key": "LiveForum",
"displayName": "论坛系统"
}
]
响应字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
| key | string | 数据库标识,用于后续接口传参 |
| displayName | string | 显示名称,用于前端展示 |
前端使用示例
// 1. 定义接口类型
interface DataSource {
key: string;
displayName: string;
}
// 2. 调用接口
const getDatabases = async (): Promise<DataSource[]> => {
const response = await axios.get('/api/CodeGeneration/databases');
return response.data;
};
// 3. 使用示例(页面加载时)
onMounted(async () => {
const databases = await getDatabases();
// 填充到下拉框
databaseOptions.value = databases;
});
✨ 2. 修改接口:表列表查询
接口信息
- 请求路径:
POST /api/CodeGeneration/{size}/{page} - 请求方法:
POST - 是否需要认证:是
- 描述:获取表列表,支持按表名和数据库筛选
请求参数
路径参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| size | number | 是 | 每页条数 |
| page | number | 是 | 页码 |
Body 参数(JSON):
{
"tableName": "User", // 可选,表名模糊搜索
"dataBase": "Admin" // 🆕 新增,数据库标识筛选
}
请求字段说明
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| tableName | string | 否 | 表名,支持模糊搜索 |
| dataBase | string | 否 | 🆕 数据库标识,不传则返回所有数据库的表 |
响应示例
{
"total": 25,
"page": 1,
"size": 10,
"pageCount": 3,
"dataSource": [
{
"tableName": "Users",
"remark": "用户表",
"dataBase": "Admin" // 🆕 新增字段
},
{
"tableName": "T_Image_Config",
"remark": "图片配置表",
"dataBase": "MiaoYuChat" // 🆕 新增字段
}
]
}
响应字段说明
| 字段名 | 类型 | 说明 |
|---|---|---|
| tableName | string | 表名 |
| remark | string | 表备注/描述 |
| dataBase | string | 🆕 表所属的数据库标识 |
前端使用示例
// 1. 定义接口类型
interface TableListItem {
tableName: string;
remark: string;
dataBase: string; // 🆕 新增字段
}
interface TableListRequest {
tableName?: string;
dataBase?: string; // 🆕 新增字段
}
// 2. 调用接口
const getTableList = async (
page: number,
size: number,
search: TableListRequest
): Promise<PagingResult<TableListItem>> => {
const response = await axios.post(
`/api/CodeGeneration/${size}/${page}`,
search
);
return response.data;
};
// 3. 使用示例(带数据库筛选)
const loadTableList = async () => {
const result = await getTableList(1, 10, {
tableName: searchKeyword.value,
dataBase: selectedDatabase.value // 🆕 传递选中的数据库
});
tableList.value = result.dataSource;
};
🔧 3. 代码生成接口参数调整
影响的接口
以下接口在调用时,需要确保 dataBase 参数正确传递:
- 获取代码:
POST /api/CodeGeneration/GetCodeAsync - 下载代码:
POST /api/CodeGeneration/DownloadAsync - 下载所有代码:
POST /api/CodeGeneration/DownloadAllAsync - 自动导入项目:
POST /api/CodeGeneration/AutoImprotProjectAsync
请求 Body 示例
{
"tableName": "T_Image_Config",
"dataBase": "MiaoYuChat", // ⚠️ 必须传递,确保准确匹配表
"type": "MiaoYu.Models"
}
前端使用示例
// 生成代码时,从表列表中获取 dataBase 并传递
const generateCode = async (table: TableListItem, type: string) => {
const response = await axios.post('/api/CodeGeneration/GetCodeAsync', {
tableName: table.tableName,
dataBase: table.dataBase, // 🆕 必须传递
type: type
});
return response.data;
};
📝 4. 前端需要修改的地方
4.1 页面布局调整
在表列表页面顶部新增数据库选择器:
<template>
<div class="code-generation-page">
<!-- 🆕 新增:数据库选择器 -->
<div class="filter-section">
<a-select
v-model:value="selectedDatabase"
placeholder="选择数据库"
style="width: 200px"
@change="handleDatabaseChange"
>
<a-select-option value="">全部数据库</a-select-option>
<a-select-option
v-for="db in databaseList"
:key="db.key"
:value="db.key"
>
{{ db.displayName }}
</a-select-option>
</a-select>
<!-- 原有的搜索框 -->
<a-input
v-model:value="searchKeyword"
placeholder="搜索表名"
style="width: 300px; margin-left: 10px"
@change="handleSearch"
/>
</div>
<!-- 表格列表 -->
<a-table :columns="columns" :data-source="tableList">
<!-- 🆕 新增:显示数据库标识列 -->
<a-table-column key="dataBase" title="数据库" data-index="dataBase" />
<a-table-column key="tableName" title="表名" data-index="tableName" />
<a-table-column key="remark" title="说明" data-index="remark" />
<!-- 其他列... -->
</a-table>
</div>
</template>
4.2 状态管理
import { ref, onMounted } from 'vue';
// 🆕 新增状态
const databaseList = ref<DataSource[]>([]);
const selectedDatabase = ref<string>(''); // 空字符串表示全部
// 原有状态
const tableList = ref<TableListItem[]>([]);
const searchKeyword = ref<string>('');
// 🆕 页面加载时获取数据库列表
onMounted(async () => {
await loadDatabases();
await loadTableList();
});
const loadDatabases = async () => {
databaseList.value = await getDatabases();
};
// 🆕 数据库切换事件
const handleDatabaseChange = () => {
loadTableList();
};
// 修改:加载表列表时传递数据库参数
const loadTableList = async () => {
const result = await getTableList(1, 10, {
tableName: searchKeyword.value,
dataBase: selectedDatabase.value // 🆕 传递数据库参数
});
tableList.value = result.dataSource;
};
4.3 生成代码时传递数据库
// ⚠️ 重要:生成代码时必须传递 dataBase
const handleGenerateCode = async (record: TableListItem) => {
const code = await generateCode({
tableName: record.tableName,
dataBase: record.dataBase, // 🆕 从表列表记录中获取
type: selectedCodeType.value
});
// 展示生成的代码...
};
⚠️ 5. 注意事项
5.1 兼容性说明
- 向后兼容:
dataBase字段为可选,不传时返回所有数据库的表(保持原有行为) - 推荐实践:建议前端始终传递
dataBase参数,避免同名表冲突
5.2 同名表处理
后端支持不同数据库中存在同名表,因此:
- 表列表中可能出现多个同名的表,通过
dataBase字段区分 - 生成代码时必须传递
dataBase参数,确保操作正确的表
5.3 UI/UX 建议
-
数据库标识显示:
- 在表名前添加数据库标签,如
[Admin] Users、[MiaoYuChat] T_Image_Config - 使用不同颜色或图标区分不同数据库
- 在表名前添加数据库标签,如
-
默认选择:
- 建议默认选择第一个数据库,而不是"全部"
- 可根据用户最近使用的数据库进行智能默认
-
表格列顺序:
- 建议顺序:数据库 → 表名 → 说明 → 操作
- 数据库列可以考虑使用标签样式展示
📚 6. 完整示例代码
// types.ts
export interface DataSource {
key: string;
displayName: string;
}
export interface TableListItem {
tableName: string;
remark: string;
dataBase: string;
}
export interface TableListRequest {
tableName?: string;
dataBase?: string;
}
// api.ts
import axios from 'axios';
export const codeGenerationApi = {
// 🆕 获取数据库列表
getDatabases: (): Promise<DataSource[]> => {
return axios.get('/api/CodeGeneration/databases').then(res => res.data);
},
// 获取表列表(已修改)
getTableList: (page: number, size: number, search: TableListRequest) => {
return axios.post(`/api/CodeGeneration/${size}/${page}`, search)
.then(res => res.data);
},
// 生成代码(已修改)
generateCode: (params: {
tableName: string;
dataBase: string;
type: string;
}) => {
return axios.post('/api/CodeGeneration/GetCodeAsync', params)
.then(res => res.data);
},
// 其他接口...
};
// page.vue
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { codeGenerationApi } from '@/api/codeGeneration';
import type { DataSource, TableListItem } from '@/types/codeGeneration';
// 状态
const databaseList = ref<DataSource[]>([]);
const selectedDatabase = ref<string>('');
const tableList = ref<TableListItem[]>([]);
const searchKeyword = ref<string>('');
const pagination = ref({ page: 1, size: 10, total: 0 });
// 生命周期
onMounted(async () => {
await loadDatabases();
await loadTableList();
});
// 加载数据库列表
const loadDatabases = async () => {
try {
databaseList.value = await codeGenerationApi.getDatabases();
// 可选:默认选择第一个数据库
// if (databaseList.value.length > 0) {
// selectedDatabase.value = databaseList.value[0].key;
// }
} catch (error) {
console.error('加载数据库列表失败:', error);
}
};
// 加载表列表
const loadTableList = async () => {
try {
const result = await codeGenerationApi.getTableList(
pagination.value.page,
pagination.value.size,
{
tableName: searchKeyword.value,
dataBase: selectedDatabase.value
}
);
tableList.value = result.dataSource;
pagination.value.total = result.total;
} catch (error) {
console.error('加载表列表失败:', error);
}
};
// 事件处理
const handleDatabaseChange = () => {
pagination.value.page = 1; // 重置页码
loadTableList();
};
const handleSearch = () => {
pagination.value.page = 1; // 重置页码
loadTableList();
};
const handleGenerateCode = async (record: TableListItem) => {
try {
const code = await codeGenerationApi.generateCode({
tableName: record.tableName,
dataBase: record.dataBase,
type: 'MiaoYu.Models'
});
// 展示代码...
} catch (error) {
console.error('生成代码失败:', error);
}
};
</script>
<template>
<div class="code-generation-page">
<!-- 筛选区域 -->
<div class="filter-section">
<a-space>
<a-select
v-model:value="selectedDatabase"
placeholder="选择数据库"
style="width: 200px"
@change="handleDatabaseChange"
>
<a-select-option value="">全部数据库</a-select-option>
<a-select-option
v-for="db in databaseList"
:key="db.key"
:value="db.key"
>
{{ db.displayName }}
</a-select-option>
</a-select>
<a-input
v-model:value="searchKeyword"
placeholder="搜索表名"
style="width: 300px"
@change="handleSearch"
/>
</a-space>
</div>
<!-- 表格 -->
<a-table
:data-source="tableList"
:pagination="{
current: pagination.page,
pageSize: pagination.size,
total: pagination.total,
onChange: (page) => {
pagination.page = page;
loadTableList();
}
}"
>
<a-table-column key="dataBase" title="数据库" data-index="dataBase">
<template #default="{ record }">
<a-tag :color="getDatabaseColor(record.dataBase)">
{{ getDatabaseDisplayName(record.dataBase) }}
</a-tag>
</template>
</a-table-column>
<a-table-column key="tableName" title="表名" data-index="tableName" />
<a-table-column key="remark" title="说明" data-index="remark" />
<a-table-column key="actions" title="操作">
<template #default="{ record }">
<a-button type="link" @click="handleGenerateCode(record)">
生成代码
</a-button>
</template>
</a-table-column>
</a-table>
</div>
</template>
<style scoped>
.code-generation-page {
padding: 20px;
}
.filter-section {
margin-bottom: 20px;
}
</style>
🎨 7. 视觉效果建议
数据库标签颜色方案
const getDatabaseColor = (databaseKey: string): string => {
const colorMap: Record<string, string> = {
'Admin': 'blue',
'MiaoYuChat': 'green',
'LiveForum': 'orange'
};
return colorMap[databaseKey] || 'default';
};
const getDatabaseDisplayName = (databaseKey: string): string => {
const database = databaseList.value.find(db => db.key === databaseKey);
return database?.displayName || databaseKey;
};
表格展示效果
┌────────────┬─────────────────┬──────────────┬────────┐
│ 数据库 │ 表名 │ 说明 │ 操作 │
├────────────┼─────────────────┼──────────────┼────────┤
│ [Admin] │ Users │ 用户表 │ 生成 │
│ [MiaoYuChat]│ T_Image_Config │ 图片配置表 │ 生成 │
│ [Admin] │ Roles │ 角色表 │ 生成 │
└────────────┴─────────────────┴──────────────┴────────┘
📞 8. 技术支持
如有疑问,请联系后端开发团队。
文档版本:v1.0
更新日期:2024年
后端版本:v2.0(支持多数据源)