library-picturebook-activity/backend/scripts/debug-menus.ts

131 lines
4.0 KiB
TypeScript
Raw Normal View History

2026-01-09 18:14:35 +08:00
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
const tenantId = 1;
// 获取租户分配的菜单ID
const tenantMenus = await prisma.tenantMenu.findMany({
where: { tenantId },
});
const menuIds = tenantMenus.map((tm) => tm.menuId);
console.log('📋 租户分配的菜单IDs:', menuIds.length, '个');
// 获取租户分配的所有菜单(包括父菜单)
const allMenus = await prisma.menu.findMany({
where: {
OR: [
{ id: { in: menuIds } },
{ children: { some: { id: { in: menuIds } } } },
],
validState: 1,
},
orderBy: {
sort: 'asc',
},
});
// 过滤出赛事活动相关的
console.log('\n📋 赛事活动相关菜单 (从数据库查询):');
const activityMenus = allMenus.filter(m => m.path?.startsWith('/student-activities'));
activityMenus.forEach(m => {
console.log(` ID: ${m.id} | ${m.name}`);
console.log(` path: ${m.path}`);
console.log(` component: ${m.component || '(null)'}`);
console.log(` parentId: ${m.parentId}`);
});
// 构建树形结构
const buildTree = (menus: any[], parentId: number | null = null): any[] => {
return menus
.filter((menu) => menu.parentId === parentId)
.map((menu) => ({
...menu,
children: buildTree(menus, menu.id),
}));
};
const menuTree = buildTree(allMenus);
// 找到赛事活动菜单树
const activityTree = menuTree.find(m => m.path === '/student-activities');
if (activityTree) {
console.log('\n📋 赛事活动菜单树 (模拟API返回):');
const printTree = (menu: any, indent = '') => {
console.log(`${indent}${menu.name} (${menu.path})`);
console.log(`${indent} component: ${menu.component || '(null)'}`);
if (menu.children && menu.children.length > 0) {
menu.children.forEach((child: any) => printTree(child, indent + ' '));
}
};
printTree(activityTree);
} else {
console.log('\n❌ 未找到赛事活动菜单树');
}
// 模拟权限过滤
const userPermissions = ['workbench:read', 'contest:activity:read', 'homework:student:read'];
const filterMenus = (menus: any[]): any[] => {
return menus
.map((menu) => {
let filteredChildren: any[] = [];
if (menu.children && menu.children.length > 0) {
filteredChildren = filterMenus(menu.children);
}
const hasPermissionField = menu.permission && menu.permission.trim() !== '';
if (hasPermissionField) {
if (!userPermissions.includes(menu.permission)) {
if (filteredChildren.length > 0) {
return { ...menu, children: filteredChildren };
}
return null;
}
}
if (!hasPermissionField) {
if (filteredChildren.length === 0 && (!menu.path || menu.path.trim() === '')) {
return null;
}
if (filteredChildren.length > 0) {
return { ...menu, children: filteredChildren };
}
return null;
}
const filtered = { ...menu };
if (filteredChildren.length > 0) {
filtered.children = filteredChildren;
}
return filtered;
})
.filter((menu) => menu !== null);
};
const filteredTree = filterMenus(menuTree);
const filteredActivityTree = filteredTree.find(m => m.path === '/student-activities');
if (filteredActivityTree) {
console.log('\n📋 权限过滤后的赛事活动菜单:');
const printTree = (menu: any, indent = '') => {
console.log(`${indent}${menu.name} (${menu.path})`);
console.log(`${indent} component: ${menu.component || '(null)'}`);
if (menu.children && menu.children.length > 0) {
menu.children.forEach((child: any) => printTree(child, indent + ' '));
}
};
printTree(filteredActivityTree);
console.log('\n📋 JSON格式 (检查component字段):');
console.log(JSON.stringify(filteredActivityTree, null, 2));
}
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect());