223 lines
6.2 KiB
JavaScript
223 lines
6.2 KiB
JavaScript
/**
|
||
* API 菜单批量导入脚本(浏览器版本)
|
||
* 在浏览器控制台中运行此脚本
|
||
*
|
||
* 使用方法:
|
||
* 1. 打开浏览器控制台(F12)
|
||
* 2. 确保已登录系统
|
||
* 3. 复制并运行以下代码
|
||
*/
|
||
|
||
// 菜单标题映射
|
||
const menuTitleMap = {
|
||
'menu.api': 'API',
|
||
'menu.api.upstreamInterface': '上游接口',
|
||
'menu.api.downstreamInterface': '下游接口',
|
||
'menu.api.appList': 'App列表',
|
||
'menu.api.requestLog': '请求日志',
|
||
'menu.api.callStatistics': '调用统计',
|
||
'menu.api.apiDebugger': 'API调试',
|
||
};
|
||
|
||
// API 路由配置
|
||
const apiRoutes = {
|
||
parent: {
|
||
name: 'API',
|
||
path: '/api',
|
||
icon: 'icon-computer',
|
||
order: 1,
|
||
},
|
||
children: [
|
||
{
|
||
path: 'upstreamInterface',
|
||
name: 'UpstreamInterface',
|
||
component: 'views/api/upstreamInterface/index',
|
||
locale: 'menu.api.upstreamInterface',
|
||
permission: 'Api.Interfaces.Query',
|
||
icon: 'icon-code',
|
||
order: 1,
|
||
},
|
||
{
|
||
path: 'downstreamInterface',
|
||
name: 'DownstreamInterface',
|
||
component: 'views/api/downstreamInterface/index',
|
||
locale: 'menu.api.downstreamInterface',
|
||
permission: 'Api.ServiceProviders.Query',
|
||
icon: 'icon-code',
|
||
order: 2,
|
||
},
|
||
{
|
||
path: 'appList',
|
||
name: 'AppList',
|
||
component: 'views/api/appList/index',
|
||
locale: 'menu.api.appList',
|
||
permission: 'Api.Applications.Query',
|
||
icon: 'icon-apps',
|
||
order: 3,
|
||
},
|
||
{
|
||
path: 'requestLog',
|
||
name: 'RequestLog',
|
||
component: 'views/api/requestLog/index',
|
||
locale: 'menu.api.requestLog',
|
||
permission: 'Api.Logs.Query',
|
||
icon: 'icon-file-text',
|
||
order: 4,
|
||
},
|
||
{
|
||
path: 'callStatistics',
|
||
name: 'CallStatistics',
|
||
component: 'views/api/callStatistics/index',
|
||
locale: 'menu.api.callStatistics',
|
||
permission: 'Api.Statistics.Query',
|
||
icon: 'icon-bar-chart',
|
||
order: 5,
|
||
},
|
||
{
|
||
path: 'apiDebugger',
|
||
name: 'ApiDebugger',
|
||
component: 'views/api/apiDebugger/index',
|
||
locale: 'menu.api.apiDebugger',
|
||
permission: 'Api.Debugger.Query',
|
||
icon: 'icon-bug',
|
||
order: 6,
|
||
},
|
||
],
|
||
};
|
||
|
||
/**
|
||
* 批量导入 API 菜单
|
||
*/
|
||
async function importApiMenus() {
|
||
try {
|
||
console.log('🚀 开始导入 API 菜单...');
|
||
|
||
// 动态导入 MenuService(需要根据实际路径调整)
|
||
const { MenuService } = await import('/src/api/rbac/generated/services/MenuService.js');
|
||
|
||
// 1. 获取已有菜单
|
||
let existingMenus = [];
|
||
try {
|
||
existingMenus = await MenuService.getRbacMenuGetMenuTree();
|
||
console.log('📋 获取到已有菜单数量:', existingMenus.length);
|
||
} catch (error) {
|
||
console.warn('⚠️ 获取已有菜单失败,将继续导入:', error);
|
||
}
|
||
|
||
// 收集已有菜单的 route
|
||
const existingRoutes = new Set();
|
||
function collectRoutes(menus) {
|
||
menus.forEach(menu => {
|
||
if (menu.route) {
|
||
existingRoutes.add(menu.route);
|
||
}
|
||
if (menu.children && menu.children.length > 0) {
|
||
collectRoutes(menu.children);
|
||
}
|
||
});
|
||
}
|
||
collectRoutes(existingMenus);
|
||
|
||
// 2. 创建父菜单(API 主菜单)
|
||
let apiParentId = null;
|
||
const existingParent = existingMenus.find(m => m.route === '/api');
|
||
|
||
if (existingParent) {
|
||
apiParentId = existingParent.id;
|
||
console.log('✅ API 主菜单已存在,ID:', apiParentId);
|
||
} else {
|
||
const parentMenu = {
|
||
pId: null,
|
||
name: apiRoutes.parent.name,
|
||
type: 1,
|
||
permissionCode: null,
|
||
icon: apiRoutes.parent.icon,
|
||
route: apiRoutes.parent.path,
|
||
component: null,
|
||
order: apiRoutes.parent.order,
|
||
isHidden: false,
|
||
isCached: false,
|
||
description: 'API 管理模块',
|
||
};
|
||
|
||
try {
|
||
const result = await MenuService.postRbacMenuCreate(parentMenu);
|
||
apiParentId = result.id;
|
||
console.log('✅ 成功创建 API 主菜单,ID:', apiParentId);
|
||
} catch (error) {
|
||
console.error('❌ 创建 API 主菜单失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 3. 创建子菜单
|
||
let successCount = 0;
|
||
let skipCount = 0;
|
||
let failCount = 0;
|
||
|
||
for (const route of apiRoutes.children) {
|
||
const routePath = `/api/${route.path}`;
|
||
|
||
// 检查是否已存在
|
||
if (existingRoutes.has(routePath)) {
|
||
skipCount++;
|
||
console.log(`⏭️ 菜单已存在,跳过: ${menuTitleMap[route.locale] || route.name} (${routePath})`);
|
||
continue;
|
||
}
|
||
|
||
const menuData = {
|
||
pId: apiParentId,
|
||
name: menuTitleMap[route.locale] || route.name,
|
||
type: 1,
|
||
permissionCode: route.permission,
|
||
icon: route.icon,
|
||
route: routePath,
|
||
component: route.component,
|
||
order: route.order,
|
||
isHidden: false,
|
||
isCached: false,
|
||
description: `从路由配置导入: ${routePath}`,
|
||
};
|
||
|
||
try {
|
||
await MenuService.postRbacMenuCreate(menuData);
|
||
successCount++;
|
||
console.log(`✅ 成功导入: ${menuData.name} (${routePath})`);
|
||
} catch (error) {
|
||
if (error.status === 400 || error.status === 409) {
|
||
skipCount++;
|
||
console.log(`⏭️ 菜单已存在,跳过: ${menuData.name} (${routePath})`);
|
||
} else {
|
||
failCount++;
|
||
console.error(`❌ 导入失败: ${menuData.name} (${routePath})`, error);
|
||
}
|
||
}
|
||
}
|
||
|
||
console.log('\n📊 === 导入完成 ===');
|
||
console.log(`✅ 成功: ${successCount} 个`);
|
||
console.log(`⏭️ 跳过: ${skipCount} 个`);
|
||
console.log(`❌ 失败: ${failCount} 个`);
|
||
console.log(`📦 总计: ${apiRoutes.children.length} 个`);
|
||
|
||
return {
|
||
success: successCount,
|
||
skip: skipCount,
|
||
fail: failCount,
|
||
total: apiRoutes.children.length,
|
||
};
|
||
} catch (error) {
|
||
console.error('❌ 批量导入菜单失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
// 导出到全局
|
||
if (typeof window !== 'undefined') {
|
||
window.importApiMenus = importApiMenus;
|
||
console.log('📝 API 菜单导入函数已挂载到 window.importApiMenus');
|
||
console.log('💡 使用方法: await window.importApiMenus()');
|
||
}
|
||
|
||
export { importApiMenus };
|