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

157 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() {
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());