library-picturebook-activity/backend/scripts/init-roles-permissions.ts
aid 418aa57ea8 Day4: 超管端设计优化 + UGC绘本创作社区P0实现
一、超管端设计优化
- 文档管理SOP体系建立,docs目录重组
- 统一用户管理:跨租户全局视角,合并用户管理+公众用户
- 活动监管全模块重构:全部活动(统计卡片+阶段筛选+SuperDetail详情页)、报名数据/作品数据/评审进度(两层合一扁平列表)、成果发布(去Tab+统计+隐藏写操作)
- 菜单精简:移除评委管理/评审规则/通知管理
- Bug修复:租户编辑丢失隐藏菜单、pageSize限制、主色统一

二、UGC绘本创作社区P0
- 数据库:10张新表(user_works/user_work_pages/work_tags等)
- 子女账号独立化:Child升级为独立User,家长切换+独立登录
- 用户作品库:CRUD+发布审核,8个API
- AI创作流程:提交→生成→保存到作品库,4个API
- 作品广场:首页改造为推荐流,标签+搜索+排序
- 内容审核(超管端):作品审核+作品管理+标签管理
- 活动联动:WorkSelector作品选择器
- 布局改造:底部5Tab(发现/创作/活动/作品库/我的)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:20:25 +08:00

577 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import * as dotenv from 'dotenv';
import * as path from 'path';
const nodeEnv = process.env.NODE_ENV || 'development';
const envFile = `.env.${nodeEnv}`;
const backendDir = path.resolve(__dirname, '..');
const envPath = path.resolve(backendDir, envFile);
dotenv.config({ path: envPath });
if (!process.env.DATABASE_URL) {
dotenv.config({ path: path.resolve(backendDir, '.env') });
}
if (!process.env.DATABASE_URL) {
console.error('DATABASE_URL not found');
process.exit(1);
}
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// ============================================
// 权限定义
// ============================================
// 基础权限(所有角色共享的权限池)
const allPermissions = [
// AI 3D建模
{ code: 'ai-3d:read', resource: 'ai-3d', action: 'read', name: '使用3D建模实验室', description: '允许使用AI 3D建模实验室' },
{ code: 'ai-3d:create', resource: 'ai-3d', action: 'create', name: '创建3D模型任务', description: '允许创建AI 3D模型生成任务' },
// 用户管理
{ code: 'user:create', resource: 'user', action: 'create', name: '创建用户', description: '允许创建新用户' },
{ code: 'user:read', resource: 'user', action: 'read', name: '查看用户', description: '允许查看用户列表和详情' },
{ code: 'user:update', resource: 'user', action: 'update', name: '更新用户', description: '允许更新用户信息' },
{ code: 'user:delete', resource: 'user', action: 'delete', name: '删除用户', description: '允许删除用户' },
{ code: 'user:password:update', resource: 'user', action: 'password:update', name: '重置密码', description: '允许重置用户密码' },
// 角色管理
{ code: 'role:create', resource: 'role', action: 'create', name: '创建角色', description: '允许创建新角色' },
{ code: 'role:read', resource: 'role', action: 'read', name: '查看角色', description: '允许查看角色列表和详情' },
{ code: 'role:update', resource: 'role', action: 'update', name: '更新角色', description: '允许更新角色信息' },
{ code: 'role:delete', resource: 'role', action: 'delete', name: '删除角色', description: '允许删除角色' },
{ code: 'role:assign', resource: 'role', action: 'assign', name: '分配角色', description: '允许给用户分配角色' },
// 权限管理
{ code: 'permission:create', resource: 'permission', action: 'create', name: '创建权限', description: '允许创建新权限' },
{ code: 'permission:read', resource: 'permission', action: 'read', name: '查看权限', description: '允许查看权限列表' },
{ code: 'permission:update', resource: 'permission', action: 'update', name: '更新权限', description: '允许更新权限信息' },
{ code: 'permission:delete', resource: 'permission', action: 'delete', name: '删除权限', description: '允许删除权限' },
// 菜单管理
{ code: 'menu:create', resource: 'menu', action: 'create', name: '创建菜单', description: '允许创建新菜单' },
{ code: 'menu:read', resource: 'menu', action: 'read', name: '查看菜单', description: '允许查看菜单列表' },
{ code: 'menu:update', resource: 'menu', action: 'update', name: '更新菜单', description: '允许更新菜单信息' },
{ code: 'menu:delete', resource: 'menu', action: 'delete', name: '删除菜单', description: '允许删除菜单' },
// 租户管理(超级租户专属)
{ code: 'tenant:create', resource: 'tenant', action: 'create', name: '创建租户', description: '允许创建租户' },
{ code: 'tenant:read', resource: 'tenant', action: 'read', name: '查看租户', description: '允许查看租户列表' },
{ code: 'tenant:update', resource: 'tenant', action: 'update', name: '更新租户', description: '允许更新租户信息' },
{ code: 'tenant:delete', resource: 'tenant', action: 'delete', name: '删除租户', description: '允许删除租户' },
// 学校管理
{ code: 'school:create', resource: 'school', action: 'create', name: '创建学校', description: '允许创建学校信息' },
{ code: 'school:read', resource: 'school', action: 'read', name: '查看学校', description: '允许查看学校信息' },
{ code: 'school:update', resource: 'school', action: 'update', name: '更新学校', description: '允许更新学校信息' },
{ code: 'school:delete', resource: 'school', action: 'delete', name: '删除学校', description: '允许删除学校信息' },
// 部门管理
{ code: 'department:create', resource: 'department', action: 'create', name: '创建部门', description: '允许创建部门' },
{ code: 'department:read', resource: 'department', action: 'read', name: '查看部门', description: '允许查看部门列表' },
{ code: 'department:update', resource: 'department', action: 'update', name: '更新部门', description: '允许更新部门信息' },
{ code: 'department:delete', resource: 'department', action: 'delete', name: '删除部门', description: '允许删除部门' },
// 年级管理
{ code: 'grade:create', resource: 'grade', action: 'create', name: '创建年级', description: '允许创建年级' },
{ code: 'grade:read', resource: 'grade', action: 'read', name: '查看年级', description: '允许查看年级列表' },
{ code: 'grade:update', resource: 'grade', action: 'update', name: '更新年级', description: '允许更新年级信息' },
{ code: 'grade:delete', resource: 'grade', action: 'delete', name: '删除年级', description: '允许删除年级' },
// 班级管理
{ code: 'class:create', resource: 'class', action: 'create', name: '创建班级', description: '允许创建班级' },
{ code: 'class:read', resource: 'class', action: 'read', name: '查看班级', description: '允许查看班级列表' },
{ code: 'class:update', resource: 'class', action: 'update', name: '更新班级', description: '允许更新班级信息' },
{ code: 'class:delete', resource: 'class', action: 'delete', name: '删除班级', description: '允许删除班级' },
// 教师管理
{ code: 'teacher:create', resource: 'teacher', action: 'create', name: '创建教师', description: '允许创建教师' },
{ code: 'teacher:read', resource: 'teacher', action: 'read', name: '查看教师', description: '允许查看教师列表' },
{ code: 'teacher:update', resource: 'teacher', action: 'update', name: '更新教师', description: '允许更新教师信息' },
{ code: 'teacher:delete', resource: 'teacher', action: 'delete', name: '删除教师', description: '允许删除教师' },
// 学生管理
{ code: 'student:create', resource: 'student', action: 'create', name: '创建学生', description: '允许创建学生' },
{ code: 'student:read', resource: 'student', action: 'read', name: '查看学生', description: '允许查看学生列表' },
{ code: 'student:update', resource: 'student', action: 'update', name: '更新学生', description: '允许更新学生信息' },
{ code: 'student:delete', resource: 'student', action: 'delete', name: '删除学生', description: '允许删除学生' },
// 活动管理(超级租户)
{ code: 'contest:create', resource: 'contest', action: 'create', name: '创建活动', description: '允许创建活动' },
{ code: 'contest:read', resource: 'contest', action: 'read', name: '查看活动', description: '允许查看活动列表' },
{ code: 'contest:update', resource: 'contest', action: 'update', name: '更新活动', description: '允许更新活动信息' },
{ code: 'contest:delete', resource: 'contest', action: 'delete', name: '删除活动', description: '允许删除活动' },
{ code: 'contest:publish', resource: 'contest', action: 'publish', name: '发布活动', description: '允许发布/取消发布活动' },
{ code: 'contest:finish', resource: 'contest', action: 'finish', name: '结束活动', description: '允许结束活动' },
// 评审规则管理
{ code: 'review-rule:create', resource: 'review-rule', action: 'create', name: '创建评审规则', description: '允许创建评审规则' },
{ code: 'review-rule:read', resource: 'review-rule', action: 'read', name: '查看评审规则', description: '允许查看评审规则' },
{ code: 'review-rule:update', resource: 'review-rule', action: 'update', name: '更新评审规则', description: '允许更新评审规则' },
{ code: 'review-rule:delete', resource: 'review-rule', action: 'delete', name: '删除评审规则', description: '允许删除评审规则' },
// 评委管理
{ code: 'judge:create', resource: 'judge', action: 'create', name: '添加评委', description: '允许添加评委' },
{ code: 'judge:read', resource: 'judge', action: 'read', name: '查看评委', description: '允许查看评委列表' },
{ code: 'judge:update', resource: 'judge', action: 'update', name: '更新评委', description: '允许更新评委信息' },
{ code: 'judge:delete', resource: 'judge', action: 'delete', name: '删除评委', description: '允许删除评委' },
{ code: 'judge:assign', resource: 'judge', action: 'assign', name: '分配评委', description: '允许为活动分配评委' },
// 活动报名(学校端)
{ code: 'registration:create', resource: 'registration', action: 'create', name: '创建报名', description: '允许报名活动' },
{ code: 'registration:read', resource: 'registration', action: 'read', name: '查看报名', description: '允许查看报名记录' },
{ code: 'registration:update', resource: 'registration', action: 'update', name: '更新报名', description: '允许更新报名信息' },
{ code: 'registration:delete', resource: 'registration', action: 'delete', name: '取消报名', description: '允许取消报名' },
{ code: 'registration:approve', resource: 'registration', action: 'approve', name: '审核报名', description: '允许审核报名' },
{ code: 'registration:audit', resource: 'registration', action: 'audit', name: '审核报名记录', description: '允许审核报名记录' },
// 参赛作品
{ code: 'work:create', resource: 'work', action: 'create', name: '上传作品', description: '允许上传参赛作品' },
{ code: 'work:read', resource: 'work', action: 'read', name: '查看作品', description: '允许查看参赛作品' },
{ code: 'work:update', resource: 'work', action: 'update', name: '更新作品', description: '允许更新作品信息' },
{ code: 'work:delete', resource: 'work', action: 'delete', name: '删除作品', description: '允许删除作品' },
{ code: 'work:submit', resource: 'work', action: 'submit', name: '提交作品', description: '允许提交作品' },
// 作品评审(评委端)
{ code: 'review:read', resource: 'review', action: 'read', name: '查看评审任务', description: '允许查看待评审作品' },
{ code: 'review:score', resource: 'review', action: 'score', name: '评审打分', description: '允许对作品打分' },
{ code: 'review:assign', resource: 'review', action: 'assign', name: '分配评审', description: '允许分配作品给评委' },
// 成果管理
{ code: 'result:read', resource: 'result', action: 'read', name: '查看成果', description: '允许查看活动结果' },
{ code: 'result:publish', resource: 'result', action: 'publish', name: '发布成果', description: '允许发布活动结果' },
{ code: 'result:award', resource: 'result', action: 'award', name: '设置奖项', description: '允许设置奖项等级' },
// 活动公告
{ code: 'notice:create', resource: 'notice', action: 'create', name: '创建公告', description: '允许创建活动公告' },
{ code: 'notice:read', resource: 'notice', action: 'read', name: '查看公告', description: '允许查看活动公告' },
{ code: 'notice:update', resource: 'notice', action: 'update', name: '更新公告', description: '允许更新公告信息' },
{ code: 'notice:delete', resource: 'notice', action: 'delete', name: '删除公告', description: '允许删除公告' },
// 作业管理
{ code: 'homework:create', resource: 'homework', action: 'create', name: '创建作业', description: '允许创建作业' },
{ code: 'homework:read', resource: 'homework', action: 'read', name: '查看作业', description: '允许查看作业列表' },
{ code: 'homework:update', resource: 'homework', action: 'update', name: '更新作业', description: '允许更新作业信息' },
{ code: 'homework:delete', resource: 'homework', action: 'delete', name: '删除作业', description: '允许删除作业' },
{ code: 'homework:publish', resource: 'homework', action: 'publish', name: '发布作业', description: '允许发布作业' },
// 作业提交
{ code: 'homework-submission:create', resource: 'homework-submission', action: 'create', name: '提交作业', description: '允许提交作业' },
{ code: 'homework-submission:read', resource: 'homework-submission', action: 'read', name: '查看作业提交', description: '允许查看作业提交记录' },
{ code: 'homework-submission:update', resource: 'homework-submission', action: 'update', name: '更新作业提交', description: '允许更新提交的作业' },
// 作业评审规则
{ code: 'homework-review-rule:create', resource: 'homework-review-rule', action: 'create', name: '创建作业评审规则', description: '允许创建作业评审规则' },
{ code: 'homework-review-rule:read', resource: 'homework-review-rule', action: 'read', name: '查看作业评审规则', description: '允许查看作业评审规则' },
{ code: 'homework-review-rule:update', resource: 'homework-review-rule', action: 'update', name: '更新作业评审规则', description: '允许更新作业评审规则' },
{ code: 'homework-review-rule:delete', resource: 'homework-review-rule', action: 'delete', name: '删除作业评审规则', description: '允许删除作业评审规则' },
// 作业评分
{ code: 'homework-score:create', resource: 'homework-score', action: 'create', name: '作业评分', description: '允许对作业评分' },
{ code: 'homework-score:read', resource: 'homework-score', action: 'read', name: '查看作业评分', description: '允许查看作业评分' },
// 字典管理
{ code: 'dict:create', resource: 'dict', action: 'create', name: '创建字典', description: '允许创建新字典' },
{ code: 'dict:read', resource: 'dict', action: 'read', name: '查看字典', description: '允许查看字典列表和详情' },
{ code: 'dict:update', resource: 'dict', action: 'update', name: '更新字典', description: '允许更新字典信息' },
{ code: 'dict:delete', resource: 'dict', action: 'delete', name: '删除字典', description: '允许删除字典' },
// 系统配置
{ code: 'config:create', resource: 'config', action: 'create', name: '创建配置', description: '允许创建新配置' },
{ code: 'config:read', resource: 'config', action: 'read', name: '查看配置', description: '允许查看配置列表和详情' },
{ code: 'config:update', resource: 'config', action: 'update', name: '更新配置', description: '允许更新配置信息' },
{ code: 'config:delete', resource: 'config', action: 'delete', name: '删除配置', description: '允许删除配置' },
// 日志管理
{ code: 'log:read', resource: 'log', action: 'read', name: '查看日志', description: '允许查看系统日志' },
{ code: 'log:delete', resource: 'log', action: 'delete', name: '删除日志', description: '允许删除系统日志' },
// 我的评审(学校端)
{ code: 'activity:read', resource: 'activity', action: 'read', name: '查看我的评审', description: '允许查看已发布的我的评审' },
{ code: 'activity:guidance', resource: 'activity', action: 'guidance', name: '指导学生', description: '允许指导学生参赛' },
];
// ============================================
// 角色定义和权限映射
// ============================================
// 超级租户角色
const superTenantRoles = [
{
code: 'super_admin',
name: '超级管理员',
description: '系统超级管理员,管理活动和系统配置',
permissions: [
// 系统管理
'user:create', 'user:read', 'user:update', 'user:delete', 'user:password:update',
'role:create', 'role:read', 'role:update', 'role:delete', 'role:assign',
'permission:create', 'permission:read', 'permission:update', 'permission:delete',
'menu:create', 'menu:read', 'menu:update', 'menu:delete',
'tenant:create', 'tenant:read', 'tenant:update', 'tenant:delete',
'dict:create', 'dict:read', 'dict:update', 'dict:delete',
'config:create', 'config:read', 'config:update', 'config:delete',
'log:read', 'log:delete',
// 活动管理
'contest:create', 'contest:read', 'contest:update', 'contest:delete', 'contest:publish', 'contest:finish',
'review-rule:create', 'review-rule:read', 'review-rule:update', 'review-rule:delete',
'judge:create', 'judge:read', 'judge:update', 'judge:delete', 'judge:assign',
'registration:read', 'registration:approve', 'registration:audit',
'work:read', 'work:update',
'review:read', 'review:assign',
'result:read', 'result:publish', 'result:award',
'notice:create', 'notice:read', 'notice:update', 'notice:delete',
],
},
{
code: 'judge',
name: '评委',
description: '活动评委,可以评审作品',
permissions: [
'activity:read', // 查看我的评审
'work:read', // 查看待评审作品
'review:read', // 查看评审任务
'review:score', // 评审打分
'notice:read', // 查看公告
],
},
];
// 普通租户(学校)角色
const normalTenantRoles = [
{
code: 'school_admin',
name: '学校管理员',
description: '学校管理员,管理学校信息、教师、学生等',
permissions: [
'user:create', 'user:read', 'user:update', 'user:delete',
'role:create', 'role:read', 'role:update', 'role:delete', 'role:assign',
'permission:read',
'menu:read',
// 学校管理
'school:create', 'school:read', 'school:update', 'school:delete',
'department:create', 'department:read', 'department:update', 'department:delete',
'grade:create', 'grade:read', 'grade:update', 'grade:delete',
'class:create', 'class:read', 'class:update', 'class:delete',
'teacher:create', 'teacher:read', 'teacher:update', 'teacher:delete',
'student:create', 'student:read', 'student:update', 'student:delete',
// 我的评审
'activity:read',
'notice:read',
// 可以查看报名和作品
'registration:read',
'work:read',
],
},
{
code: 'teacher',
name: '教师',
description: '教师角色,可以报名活动、指导学生、管理作业',
permissions: [
// AI 3D建模工作台入口
'ai-3d:read', 'ai-3d:create', // 使用AI 3D建模实验室
// 查看基础信息
'grade:read',
'class:read',
'student:read',
// 我的评审
'activity:read', // 查看我的评审列表
'activity:guidance', // 指导学生参赛
'notice:read', // 查看活动公告
'registration:create', 'registration:read', 'registration:update', 'registration:delete', // 报名管理
'work:create', 'work:read', 'work:update', 'work:submit', // 指导学生上传作品
// 作业管理
'homework:create', 'homework:read', 'homework:update', 'homework:delete', 'homework:publish',
'homework-submission:read',
'homework-review-rule:create', 'homework-review-rule:read', 'homework-review-rule:update', 'homework-review-rule:delete',
'homework-score:create', 'homework-score:read',
],
},
{
code: 'student',
name: '学生',
description: '学生角色,可以查看活动、上传作品、提交作业',
permissions: [
// AI 3D建模工作台入口
'ai-3d:read', 'ai-3d:create', // 使用AI 3D建模实验室
// 我的评审
'activity:read', // 查看我的评审列表
'notice:read', // 查看活动公告
'registration:read', // 查看自己的报名记录
'work:create', 'work:read', 'work:update', 'work:submit', // 上传/管理自己的作品
// 作业
'homework:read', // 查看作业
'homework-submission:create', 'homework-submission:read', 'homework-submission:update', // 提交作业
'homework-score:read', // 查看自己的作业评分
],
},
];
// ============================================
// 初始化函数
// ============================================
/**
* 为租户创建权限
*/
async function createPermissions(tenantId: number, permissionCodes: string[]) {
const createdPermissions: { [code: string]: number } = {};
for (const code of permissionCodes) {
const permDef = allPermissions.find(p => p.code === code);
if (!permDef) {
console.log(` ⚠️ 权限定义不存在: ${code}`);
continue;
}
// 检查是否已存在
let permission = await prisma.permission.findFirst({
where: { tenantId, code },
});
if (!permission) {
permission = await prisma.permission.create({
data: {
tenantId,
code: permDef.code,
resource: permDef.resource,
action: permDef.action,
name: permDef.name,
description: permDef.description,
validState: 1,
},
});
console.log(` ✓ 创建权限: ${code}`);
}
createdPermissions[code] = permission.id;
}
return createdPermissions;
}
/**
* 为租户创建角色并分配权限
*/
async function createRoleWithPermissions(
tenantId: number,
roleConfig: { code: string; name: string; description: string; permissions: string[] },
permissionMap: { [code: string]: number }
) {
// 创建或获取角色
let role = await prisma.role.findFirst({
where: { tenantId, code: roleConfig.code },
});
if (!role) {
role = await prisma.role.create({
data: {
tenantId,
code: roleConfig.code,
name: roleConfig.name,
description: roleConfig.description,
validState: 1,
},
});
console.log(` ✓ 创建角色: ${roleConfig.name} (${roleConfig.code})`);
} else {
// 更新角色信息
role = await prisma.role.update({
where: { id: role.id },
data: {
name: roleConfig.name,
description: roleConfig.description,
},
});
console.log(` ✓ 更新角色: ${roleConfig.name} (${roleConfig.code})`);
}
// 分配权限
const existingRolePermissions = await prisma.rolePermission.findMany({
where: { roleId: role.id },
select: { permissionId: true },
});
const existingPermissionIds = new Set(existingRolePermissions.map(rp => rp.permissionId));
let addedCount = 0;
for (const permCode of roleConfig.permissions) {
const permissionId = permissionMap[permCode];
if (!permissionId) {
console.log(` ⚠️ 权限不存在: ${permCode}`);
continue;
}
if (!existingPermissionIds.has(permissionId)) {
await prisma.rolePermission.create({
data: {
roleId: role.id,
permissionId,
},
});
addedCount++;
}
}
if (addedCount > 0) {
console.log(` 添加了 ${addedCount} 个权限`);
}
return role;
}
/**
* 初始化超级租户的角色和权限
*/
async function initSuperTenantRoles() {
console.log('\n🚀 开始初始化超级租户角色和权限...\n');
// 查找超级租户
const superTenant = await prisma.tenant.findFirst({
where: { isSuper: 1, validState: 1 },
});
if (!superTenant) {
console.error('❌ 超级租户不存在!请先运行 init:super-tenant');
return;
}
console.log(`找到超级租户: ${superTenant.name} (${superTenant.code})\n`);
// 收集所有需要的权限码
const allPermissionCodes = new Set<string>();
superTenantRoles.forEach(role => {
role.permissions.forEach(code => allPermissionCodes.add(code));
});
// 创建权限
console.log('📝 创建权限...');
const permissionMap = await createPermissions(superTenant.id, Array.from(allPermissionCodes));
console.log(`✅ 共 ${Object.keys(permissionMap).length} 个权限\n`);
// 创建角色
console.log('👥 创建角色...');
for (const roleConfig of superTenantRoles) {
await createRoleWithPermissions(superTenant.id, roleConfig, permissionMap);
}
console.log('\n✅ 超级租户角色和权限初始化完成!');
}
/**
* 初始化普通租户的角色和权限
*/
async function initNormalTenantRoles(tenantCode: string) {
console.log(`\n🚀 开始初始化租户 "${tenantCode}" 的角色和权限...\n`);
// 查找租户
const tenant = await prisma.tenant.findFirst({
where: { code: tenantCode, validState: 1 },
});
if (!tenant) {
console.error(`❌ 租户 "${tenantCode}" 不存在!`);
return;
}
if (tenant.isSuper === 1) {
console.log('⚠️ 这是超级租户,请使用 --super 选项');
return;
}
console.log(`找到租户: ${tenant.name} (${tenant.code})\n`);
// 收集所有需要的权限码
const allPermissionCodes = new Set<string>();
normalTenantRoles.forEach(role => {
role.permissions.forEach(code => allPermissionCodes.add(code));
});
// 创建权限
console.log('📝 创建权限...');
const permissionMap = await createPermissions(tenant.id, Array.from(allPermissionCodes));
console.log(`✅ 共 ${Object.keys(permissionMap).length} 个权限\n`);
// 创建角色
console.log('👥 创建角色...');
for (const roleConfig of normalTenantRoles) {
await createRoleWithPermissions(tenant.id, roleConfig, permissionMap);
}
// 输出角色信息
console.log('\n📊 角色权限概览:');
for (const roleConfig of normalTenantRoles) {
console.log(` ${roleConfig.name} (${roleConfig.code}): ${roleConfig.permissions.length} 个权限`);
}
console.log(`\n✅ 租户 "${tenantCode}" 角色和权限初始化完成!`);
}
/**
* 初始化所有普通租户的角色和权限
*/
async function initAllNormalTenantRoles() {
console.log('\n🚀 开始初始化所有普通租户的角色和权限...\n');
// 查找所有普通租户
const normalTenants = await prisma.tenant.findMany({
where: { isSuper: { not: 1 }, validState: 1 },
});
if (normalTenants.length === 0) {
console.log('⚠️ 没有找到普通租户');
return;
}
console.log(`找到 ${normalTenants.length} 个普通租户\n`);
for (const tenant of normalTenants) {
await initNormalTenantRoles(tenant.code);
console.log('');
}
console.log('\n✅ 所有普通租户角色和权限初始化完成!');
}
// ============================================
// 主函数
// ============================================
async function main() {
const args = process.argv.slice(2);
const isSuper = args.includes('--super');
const isAll = args.includes('--all');
const tenantCode = args.find(arg => !arg.startsWith('--'));
try {
if (isSuper) {
await initSuperTenantRoles();
} else if (isAll) {
await initAllNormalTenantRoles();
} else if (tenantCode) {
await initNormalTenantRoles(tenantCode);
} else {
console.log('使用方法:');
console.log(' 初始化超级租户角色: ts-node scripts/init-roles-permissions.ts --super');
console.log(' 初始化指定租户角色: ts-node scripts/init-roles-permissions.ts <租户编码>');
console.log(' 初始化所有普通租户: ts-node scripts/init-roles-permissions.ts --all');
process.exit(1);
}
} finally {
await prisma.$disconnect();
}
}
main()
.then(() => {
console.log('\n🎉 脚本执行完成!');
process.exit(0);
})
.catch((error) => {
console.error('\n💥 脚本执行失败:', error);
process.exit(1);
});