import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); async function main() { console.log('🔧 更新赛事活动菜单结构...\n'); // 1. 删除赛事管理下的赛事活动菜单 console.log('📝 步骤1: 移除赛事管理下的赛事活动菜单'); const oldActivityMenu = await prisma.menu.findFirst({ where: { path: '/contests/activities' } }); if (oldActivityMenu) { // 先删除租户菜单关联 await prisma.tenantMenu.deleteMany({ where: { menuId: oldActivityMenu.id } }); // 再删除菜单 await prisma.menu.delete({ where: { id: oldActivityMenu.id } }); console.log(' ✅ 已删除旧的赛事活动菜单'); } else { console.log(' ⏭️ 旧菜单不存在,跳过'); } // 2. 更新独立的赛事活动菜单(改为父菜单,不需要 component) console.log('\n📝 步骤2: 更新赛事活动为父级菜单'); let activityParent = await prisma.menu.findFirst({ where: { path: '/student-activities' } }); if (activityParent) { await prisma.menu.update({ where: { id: activityParent.id }, data: { component: null, // 父菜单不需要组件 } }); console.log(' ✅ 已更新为父级菜单'); } else { // 如果不存在,创建它 activityParent = await prisma.menu.create({ data: { name: '赛事活动', path: '/student-activities', component: null, icon: 'TrophyOutlined', permission: 'contest:activity:read', sort: 10, parentId: null, validState: 1, } }); console.log(' ✅ 已创建父级菜单'); } // 3. 创建三个子菜单 console.log('\n📝 步骤3: 创建子菜单'); const subMenus = [ { name: '我的指导', path: '/student-activities/guidance', component: 'activities/Guidance', permission: 'contest:activity:read', sort: 1, }, { name: '评审作品', path: '/student-activities/review', component: 'activities/Review', permission: 'contest:activity:read', sort: 2, }, { name: '预设评语', path: '/student-activities/comments', component: 'activities/Comments', permission: 'contest:activity:read', sort: 3, }, ]; for (const menuData of subMenus) { const existing = await prisma.menu.findFirst({ where: { path: menuData.path } }); if (existing) { console.log(` ⏭️ ${menuData.name} 已存在`); } else { await prisma.menu.create({ data: { ...menuData, parentId: activityParent.id, validState: 1, } }); console.log(` ✅ 已创建: ${menuData.name}`); } } // 4. 为租户分配新菜单 console.log('\n📝 步骤4: 分配菜单给租户'); const tenants = await prisma.tenant.findMany({ select: { id: true, name: true } }); const allMenus = await prisma.menu.findMany({ where: { OR: [ { id: activityParent.id }, { parentId: activityParent.id } ] } }); for (const tenant of tenants) { for (const menu of allMenus) { const existing = await prisma.tenantMenu.findFirst({ where: { tenantId: tenant.id, menuId: menu.id } }); if (!existing) { await prisma.tenantMenu.create({ data: { tenantId: tenant.id, menuId: menu.id } }); } } console.log(` ✅ 已分配给租户: ${tenant.name}`); } // 5. 显示最终菜单结构 console.log('\n📋 最终菜单结构:'); const finalMenus = await prisma.menu.findMany({ where: { OR: [ { id: activityParent.id }, { parentId: activityParent.id } ] }, orderBy: { sort: 'asc' } }); finalMenus.forEach(m => { const prefix = m.parentId ? ' ' : ''; console.log(`${prefix}- ${m.name} (${m.path})`); }); console.log('\n✅ 菜单更新完成!'); } main() .catch(console.error) .finally(() => prisma.$disconnect());