front/scripts/import-api-menus-simple.ts
2026-01-24 11:55:01 +08:00

224 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* API 菜单批量导入脚本(简化版)
* 直接在浏览器控制台运行
*
* 使用方法:
* 1. 打开浏览器控制台(F12)
* 2. 确保已登录系统
* 3. 复制整个脚本内容到控制台运行
*/
// API 菜单配置数据
const API_MENUS_CONFIG = [
// 父菜单(API 目录)
{
pId: null,
name: 'API',
type: 1,
permissionCode: null,
icon: 'icon-computer',
route: '/api',
component: null,
order: 1,
isHidden: false,
isCached: false,
description: 'API 管理模块',
},
// 子菜单
{
name: '上游接口',
type: 1,
permissionCode: 'Api.Interfaces.Query',
icon: 'icon-code',
route: '/api/upstreamInterface',
component: 'views/api/upstreamInterface/index',
order: 1,
isHidden: false,
isCached: false,
description: '上游接口管理',
},
{
name: '下游接口',
type: 1,
permissionCode: 'Api.ServiceProviders.Query',
icon: 'icon-code',
route: '/api/downstreamInterface',
component: 'views/api/downstreamInterface/index',
order: 2,
isHidden: false,
isCached: false,
description: '下游接口管理',
},
{
name: 'App列表',
type: 1,
permissionCode: 'Api.Applications.Query',
icon: 'icon-apps',
route: '/api/appList',
component: 'views/api/appList/index',
order: 3,
isHidden: false,
isCached: false,
description: 'App列表管理',
},
{
name: '请求日志',
type: 1,
permissionCode: 'Api.Logs.Query',
icon: 'icon-file-text',
route: '/api/requestLog',
component: 'views/api/requestLog/index',
order: 4,
isHidden: false,
isCached: false,
description: '请求日志查看',
},
{
name: '调用统计',
type: 1,
permissionCode: 'Api.Statistics.Query',
icon: 'icon-bar-chart',
route: '/api/callStatistics',
component: 'views/api/callStatistics/index',
order: 5,
isHidden: false,
isCached: false,
description: '调用统计分析',
},
{
name: 'API调试',
type: 1,
permissionCode: 'Api.Debugger.Query',
icon: 'icon-bug',
route: '/api/apiDebugger',
component: 'views/api/apiDebugger/index',
order: 6,
isHidden: false,
isCached: false,
description: 'API调试工具',
},
];
/**
* 批量导入 API 菜单
*/
async function importApiMenus() {
try {
console.log('🚀 开始导入 API 菜单...');
// 动态导入 MenuService
const { MenuService } = await import('@/api/rbac/generated/services/MenuService');
// 1. 获取已有菜单
let existingMenus = [];
try {
existingMenus = await MenuService.getRbacMenuGetMenuTree();
console.log('📋 获取到已有菜单数量:', existingMenus.length);
} catch (error) {
console.warn('⚠️ 获取已有菜单失败,将继续导入:', error);
}
// 收集已有菜单的 route 和 ID
const existingRoutes = new Map();
function collectRoutes(menus, parentId = null) {
menus.forEach(menu => {
if (menu.route) {
existingRoutes.set(menu.route, { id: menu.id, parentId });
}
if (menu.children && menu.children.length > 0) {
collectRoutes(menu.children, menu.id);
}
});
}
collectRoutes(existingMenus);
// 2. 创建父菜单(API 主菜单)
let apiParentId = null;
const parentMenu = API_MENUS_CONFIG[0];
const existingParent = existingRoutes.get('/api');
if (existingParent) {
apiParentId = existingParent.id;
console.log('✅ API 主菜单已存在,ID:', apiParentId);
} else {
try {
const result = await MenuService.postRbacMenuCreate(parentMenu);
apiParentId = result.id;
console.log('✅ 成功创建 API 主菜单,ID:', apiParentId);
} catch (error: any) {
if (error.status === 400 || error.status === 409) {
// 菜单已存在,尝试查找
const allMenus = await MenuService.getRbacMenuGetMenuTree();
const found = allMenus.find((m: any) => m.route === '/api');
if (found) {
apiParentId = found.id;
console.log('✅ API 主菜单已存在,ID:', apiParentId);
}
} else {
console.error('❌ 创建 API 主菜单失败:', error);
throw error;
}
}
}
// 3. 创建子菜单
const childMenus = API_MENUS_CONFIG.slice(1);
let successCount = 0;
let skipCount = 0;
let failCount = 0;
for (const menuConfig of childMenus) {
const menuData = {
...menuConfig,
pId: apiParentId,
};
// 检查是否已存在
if (existingRoutes.has(menuData.route)) {
skipCount++;
console.log(`⏭️ 菜单已存在,跳过: ${menuData.name} (${menuData.route})`);
continue;
}
try {
await MenuService.postRbacMenuCreate(menuData);
successCount++;
console.log(`✅ 成功导入: ${menuData.name} (${menuData.route})`);
} catch (error: any) {
if (error.status === 400 || error.status === 409) {
skipCount++;
console.log(`⏭️ 菜单已存在,跳过: ${menuData.name} (${menuData.route})`);
} else {
failCount++;
console.error(`❌ 导入失败: ${menuData.name} (${menuData.route})`, error);
}
}
}
console.log('\n📊 === 导入完成 ===');
console.log(`✅ 成功: ${successCount} 个`);
console.log(`⏭️ 跳过: ${skipCount} 个`);
console.log(`❌ 失败: ${failCount} 个`);
console.log(`📦 总计: ${childMenus.length} 个`);
return {
success: successCount,
skip: skipCount,
fail: failCount,
total: childMenus.length,
};
} catch (error) {
console.error('❌ 批量导入菜单失败:', error);
throw error;
}
}
// 如果在浏览器环境中,挂载到 window
if (typeof window !== 'undefined') {
(window as any).importApiMenus = importApiMenus;
console.log('📝 API 菜单导入函数已挂载到 window.importApiMenus');
console.log('💡 使用方法: await window.importApiMenus()');
}
export { importApiMenus, API_MENUS_CONFIG };