// 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'; const prisma = new PrismaClient(); async function main() { console.log('🚀 开始创建 LinkSea 普通租户...\n'); const tenantCode = 'linksea'; const menuNames = ['活动管理', '系统管理']; // 1. 查找或创建租户 console.log(`📋 步骤 1: 查找或创建租户 "${tenantCode}"...`); let tenant = await prisma.tenant.findUnique({ where: { code: tenantCode }, }); if (!tenant) { // 创建普通租户 tenant = await prisma.tenant.create({ data: { name: 'LinkSea 租户', code: tenantCode, domain: tenantCode, description: 'LinkSea 普通租户', isSuper: 0, validState: 1, }, }); console.log(`✅ 租户创建成功: ${tenant.name} (${tenant.code})\n`); } else { if (tenant.validState !== 1) { console.error(`❌ 错误: 租户 "${tenantCode}" 状态无效!`); process.exit(1); } console.log(`✅ 找到租户: ${tenant.name} (${tenant.code})\n`); } // 2. 查找指定的菜单(顶级菜单) console.log(`📋 步骤 2: 查找菜单 "${menuNames.join('", "')}"...`); const menus = await prisma.menu.findMany({ where: { name: { in: menuNames }, parentId: null, // 只查找顶级菜单 validState: 1, }, }); if (menus.length === 0) { console.error(`❌ 错误: 未找到指定的菜单!`); console.error(` 请确保菜单 "${menuNames.join('", "')}" 已初始化`); console.error(` 运行: pnpm init:menus`); process.exit(1); } if (menus.length !== menuNames.length) { const foundMenuNames = menus.map((m) => m.name); const missingMenus = menuNames.filter( (name) => !foundMenuNames.includes(name), ); console.warn(`⚠️ 警告: 部分菜单未找到: ${missingMenus.join(', ')}`); console.log(` 找到的菜单: ${foundMenuNames.join(', ')}\n`); } else { console.log(`✅ 找到 ${menus.length} 个菜单:`); menus.forEach((menu) => { console.log(` ✓ ${menu.name}`); }); console.log(''); } // 3. 递归获取菜单及其所有子菜单 console.log(`📋 步骤 3: 获取菜单及其所有子菜单...`); const menuIds = new Set(); // 递归函数:获取菜单及其所有子菜单的ID async function getMenuAndChildrenIds(menuId: number) { menuIds.add(menuId); // 获取所有子菜单 const children = await prisma.menu.findMany({ where: { parentId: menuId, validState: 1, }, }); // 递归获取子菜单的子菜单 for (const child of children) { await getMenuAndChildrenIds(child.id); } } // 为每个顶级菜单获取所有子菜单 for (const menu of menus) { await getMenuAndChildrenIds(menu.id); } const menuIdArray = Array.from(menuIds); console.log(`✅ 共找到 ${menuIdArray.length} 个菜单(包括子菜单)\n`); // 4. 获取租户已分配的菜单 console.log(`📋 步骤 4: 检查租户已分配的菜单...`); const existingTenantMenus = await prisma.tenantMenu.findMany({ where: { tenantId: tenant.id, }, select: { menuId: true, }, }); const existingMenuIds = new Set(existingTenantMenus.map((tm) => tm.menuId)); // 5. 为租户分配菜单(只分配新的菜单) console.log(`📋 步骤 5: 为租户分配菜单...`); const menusToAdd = menuIdArray.filter((id) => !existingMenuIds.has(id)); if (menusToAdd.length === 0) { console.log(`✅ 租户已拥有所有指定的菜单\n`); } else { let addedCount = 0; const menuNamesToAdd: string[] = []; for (const menuId of menusToAdd) { const menu = await prisma.menu.findUnique({ where: { id: menuId }, select: { name: true }, }); await prisma.tenantMenu.create({ data: { tenantId: tenant.id, menuId: menuId, }, }); addedCount++; if (menu) { menuNamesToAdd.push(menu.name); } } console.log(`✅ 为租户添加了 ${addedCount} 个菜单:`); menuNamesToAdd.forEach((name) => { console.log(` ✓ ${name}`); }); console.log( `\n✅ 租户现在拥有 ${menuIdArray.length} 个菜单(包括子菜单)\n`, ); } // 6. 验证结果 console.log('📊 初始化结果:'); console.log('========================================'); console.log('租户信息:'); console.log(` 租户编码: ${tenant.code}`); console.log(` 租户名称: ${tenant.name}`); console.log(` 租户类型: ${tenant.isSuper === 1 ? '超级租户' : '普通租户'}`); console.log(` 访问链接: http://your-domain.com/?tenant=${tenant.code}`); console.log('========================================'); console.log('分配的菜单:'); console.log(` 顶级菜单: ${menuNames.join(', ')}`); console.log(` 菜单总数: ${menuIdArray.length} 个(包括子菜单)`); console.log('========================================'); console.log('\n💡 提示:'); console.log(' 如需创建管理员账号,请运行: pnpm init:tenant-admin linksea'); console.log('========================================'); } main() .then(() => { console.log('\n🎉 LinkSea 租户创建脚本执行完成!'); process.exit(0); }) .catch((error) => { console.error('\n💥 LinkSea 租户创建脚本执行失败:', error); process.exit(1); }) .finally(async () => { await prisma.$disconnect(); });