224 lines
6.1 KiB
TypeScript
224 lines
6.1 KiB
TypeScript
/**
|
||
* 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 };
|