HuanMengAdmin/admin-client/前端接口对接文档.md
2025-11-08 02:39:31 +08:00

15 KiB
Raw Permalink Blame History

低代码生成平台 - 前端接口对接文档

📋 更新概述

本次后端更新新增了数据库选择功能,支持按数据库筛选表列表。前端需要相应修改以支持以下功能:

  1. 新增接口:获取数据库列表
  2. 增强接口:表列表接口支持按数据库筛选
  3. 返回数据变更:表列表返回数据新增 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 参数正确传递:

  1. 获取代码POST /api/CodeGeneration/GetCodeAsync
  2. 下载代码POST /api/CodeGeneration/DownloadAsync
  3. 下载所有代码POST /api/CodeGeneration/DownloadAllAsync
  4. 自动导入项目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 建议

  1. 数据库标识显示

    • 在表名前添加数据库标签,如 [Admin] Users[MiaoYuChat] T_Image_Config
    • 使用不同颜色或图标区分不同数据库
  2. 默认选择

    • 建议默认选择第一个数据库,而不是"全部"
    • 可根据用户最近使用的数据库进行智能默认
  3. 表格列顺序

    • 建议顺序:数据库 → 表名 → 说明 → 操作
    • 数据库列可以考虑使用标签样式展示

📚 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(支持多数据源)