// eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck // 加载环境变量(必须在其他导入之前) import * as dotenv from 'dotenv'; import * as path from 'path'; // 根据 NODE_ENV 加载对应的环境配置文件 const nodeEnv = process.env.NODE_ENV || 'development'; const envFile = `.env.${nodeEnv}`; // scripts 目录的父目录就是 backend 目录 const backendDir = path.resolve(__dirname, '..'); const envPath = path.resolve(backendDir, envFile); // 尝试加载环境特定的配置文件 dotenv.config({ path: envPath }); // 如果环境特定文件不存在,尝试加载默认的 .env 文件 if (!process.env.DATABASE_URL) { dotenv.config({ path: path.resolve(backendDir, '.env') }); } // 验证必要的环境变量 if (!process.env.DATABASE_URL) { console.error('❌ 错误: 未找到 DATABASE_URL 环境变量'); console.error(` 请确保存在以下文件之一:`); console.error(` - ${envPath}`); console.error(` - ${path.resolve(backendDir, '.env')}`); console.error(` 或者设置 NODE_ENV 环境变量(当前: ${nodeEnv})`); process.exit(1); } import { PrismaClient } from '@prisma/client'; import * as bcrypt from 'bcrypt'; const prisma = new PrismaClient(); async function main() { console.log('🚀 开始初始化超级租户...\n'); // 检查是否已存在超级租户 let superTenant = await prisma.tenant.findFirst({ where: { isSuper: 1 }, }); if (superTenant) { console.log('⚠️ 超级租户已存在,将更新菜单分配'); console.log(` 租户编码: ${superTenant.code}\n`); } else { // 创建超级租户 superTenant = await prisma.tenant.create({ data: { name: '超级租户', code: 'super', domain: 'super', description: '系统超级租户,拥有所有权限', isSuper: 1, validState: 1, }, }); console.log('✅ 超级租户创建成功!'); console.log(` 租户ID: ${superTenant.id}`); console.log(` 租户编码: ${superTenant.code}`); console.log(` 租户名称: ${superTenant.name}\n`); } // 创建或获取超级管理员用户 console.log('📋 步骤 2: 创建或获取超级管理员用户...\n'); let superAdmin = await prisma.user.findFirst({ where: { tenantId: superTenant.id, username: 'admin', }, }); if (!superAdmin) { const hashedPassword = await bcrypt.hash('admin@super', 10); superAdmin = await prisma.user.create({ data: { tenantId: superTenant.id, username: 'admin', password: hashedPassword, nickname: '超级管理员', email: 'admin@super.com', validState: 1, }, }); console.log('✅ 超级管理员用户创建成功!'); console.log(` 用户名: ${superAdmin.username}`); console.log(` 密码: admin@super`); console.log(` 用户ID: ${superAdmin.id}\n`); } else { console.log('✅ 超级管理员用户已存在'); console.log(` 用户名: ${superAdmin.username}`); console.log(` 用户ID: ${superAdmin.id}\n`); } // 创建或获取超级管理员角色 console.log('📋 步骤 3: 创建或获取超级管理员角色...\n'); let superAdminRole = await prisma.role.findFirst({ where: { tenantId: superTenant.id, code: 'super_admin', }, }); if (!superAdminRole) { superAdminRole = await prisma.role.create({ data: { tenantId: superTenant.id, name: '超级管理员', code: 'super_admin', description: '超级管理员角色,拥有所有权限', validState: 1, }, }); console.log('✅ 超级管理员角色创建成功!'); console.log(` 角色编码: ${superAdminRole.code}\n`); } else { console.log('✅ 超级管理员角色已存在'); console.log(` 角色编码: ${superAdminRole.code}\n`); } // 将超级管理员角色分配给用户 const existingUserRole = await prisma.userRole.findUnique({ where: { userId_roleId: { userId: superAdmin.id, roleId: superAdminRole.id, }, }, }); if (!existingUserRole) { await prisma.userRole.create({ data: { userId: superAdmin.id, roleId: superAdminRole.id, }, }); console.log('✅ 超级管理员角色已分配给用户'); } else { console.log('✅ 超级管理员角色已分配给用户,跳过'); } console.log('💡 提示: 权限初始化请使用 init:admin:permissions 脚本\n'); // 为超级租户分配所有菜单 console.log('📋 步骤 4: 为超级租户分配所有菜单...\n'); // 获取所有有效菜单 const allMenus = await prisma.menu.findMany({ where: { validState: 1, }, orderBy: [{ sort: 'asc' }, { id: 'asc' }], }); if (allMenus.length === 0) { console.log('⚠️ 警告: 数据库中没有任何菜单'); console.log(' 请先运行 pnpm init:menus 初始化菜单'); } else { console.log(` 找到 ${allMenus.length} 个菜单\n`); // 获取超级租户已分配的菜单 const existingTenantMenus = await prisma.tenantMenu.findMany({ where: { tenantId: superTenant.id, }, select: { menuId: true, }, }); const existingMenuIds = new Set(existingTenantMenus.map((tm) => tm.menuId)); // 为超级租户分配所有菜单(包括新增的菜单) let addedCount = 0; const menuNames: string[] = []; for (const menu of allMenus) { if (!existingMenuIds.has(menu.id)) { await prisma.tenantMenu.create({ data: { tenantId: superTenant.id, menuId: menu.id, }, }); addedCount++; menuNames.push(menu.name); } } if (addedCount > 0) { console.log(`✅ 为超级租户添加了 ${addedCount} 个菜单:`); menuNames.forEach((name) => { console.log(` ✓ ${name}`); }); console.log(`\n✅ 超级租户现在拥有 ${allMenus.length} 个菜单\n`); } else { console.log(`✅ 超级租户已拥有所有菜单(${allMenus.length} 个)\n`); } } // 创建租户管理菜单(如果不存在) console.log('📋 步骤 5: 创建租户管理菜单(如果不存在)...\n'); // 查找系统管理菜单(父菜单) const systemMenu = await prisma.menu.findFirst({ where: { name: '系统管理', parentId: null, }, }); if (systemMenu) { // 检查租户管理菜单是否已存在 const existingTenantMenu = await prisma.menu.findFirst({ where: { name: '租户管理', path: '/system/tenants', }, }); let tenantMenu; if (!existingTenantMenu) { tenantMenu = await prisma.menu.create({ data: { name: '租户管理', path: '/system/tenants', icon: 'TeamOutlined', component: 'system/tenants/Index', parentId: systemMenu.id, permission: 'tenant:read', sort: 7, validState: 1, }, }); console.log('✅ 租户管理菜单创建成功'); // 为超级租户分配租户管理菜单 await prisma.tenantMenu.create({ data: { tenantId: superTenant.id, menuId: tenantMenu.id, }, }); console.log('✅ 租户管理菜单已分配给超级租户\n'); } else { tenantMenu = existingTenantMenu; console.log('✅ 租户管理菜单已存在'); // 检查是否已分配 const existingTenantMenuRelation = await prisma.tenantMenu.findFirst({ where: { tenantId: superTenant.id, menuId: tenantMenu.id, }, }); if (!existingTenantMenuRelation) { await prisma.tenantMenu.create({ data: { tenantId: superTenant.id, menuId: tenantMenu.id, }, }); console.log('✅ 租户管理菜单已分配给超级租户\n'); } else { console.log('✅ 租户管理菜单已分配给超级租户,跳过\n'); } } } else { console.log('⚠️ 警告:未找到系统管理菜单,无法创建租户管理菜单\n'); } // 验证菜单分配结果 const finalMenus = await prisma.tenantMenu.findMany({ where: { tenantId: superTenant.id, }, include: { menu: true, }, }); console.log('📊 初始化结果:'); console.log('========================================'); console.log('超级租户信息:'); console.log(` 租户编码: ${superTenant.code}`); console.log(` 租户名称: ${superTenant.name}`); console.log(` 访问链接: http://your-domain.com/?tenant=${superTenant.code}`); console.log('========================================'); console.log('超级管理员登录信息:'); console.log(` 用户名: ${superAdmin.username}`); console.log(` 密码: admin@super`); console.log(` 租户编码: ${superTenant.code}`); console.log('========================================'); console.log('菜单分配情况:'); console.log(` 已分配菜单数: ${finalMenus.length}`); if (finalMenus.length > 0) { const topLevelMenus = finalMenus.filter((tm) => !tm.menu.parentId); console.log(` 顶级菜单数: ${topLevelMenus.length}`); } console.log('========================================'); console.log('\n💡 提示:'); console.log(' 权限初始化请使用: pnpm init:admin:permissions'); console.log(' 菜单初始化请使用: pnpm init:menus'); console.log('========================================'); } main() .then(() => { console.log('\n🎉 初始化脚本执行完成!'); process.exit(0); }) .catch((error) => { console.error('\n💥 初始化脚本执行失败:', error); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });