| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370 |
- #!/usr/bin/env python3
- """
- 创建RBAC权限管理相关数据库表
- """
- import pymysql
- from dotenv import load_dotenv
- import os
- load_dotenv()
- def get_db_connection():
- """获取数据库连接"""
- try:
- config = {
- 'host': os.getenv('DB_HOST', 'localhost'),
- 'port': int(os.getenv('DB_PORT', 3306)),
- 'user': os.getenv('DB_USER', 'root'),
- 'password': os.getenv('DB_PASSWORD', 'admin'),
- 'database': os.getenv('DB_NAME', 'lq_db'),
- 'charset': 'utf8mb4',
- 'autocommit': True
- }
- return pymysql.connect(**config)
- except Exception as e:
- print(f"数据库连接失败: {e}")
- return None
- def create_rbac_tables():
- """创建RBAC权限管理表"""
- print("🗄️ 创建RBAC权限管理表...")
- print("=" * 60)
-
- conn = get_db_connection()
- if not conn:
- print("❌ 数据库连接失败")
- return False
-
- cursor = conn.cursor()
-
- try:
- # 1. 菜单表 - 存储系统菜单结构
- print("📋 创建菜单表 (menus)...")
- cursor.execute("""
- CREATE TABLE IF NOT EXISTS menus (
- id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
- parent_id CHAR(36) NULL,
- name VARCHAR(100) NOT NULL COMMENT '菜单名称',
- title VARCHAR(100) NOT NULL COMMENT '菜单标题',
- path VARCHAR(200) NULL COMMENT '菜单路径',
- component VARCHAR(200) NULL COMMENT '组件路径',
- icon VARCHAR(50) NULL COMMENT '菜单图标',
- sort_order INT DEFAULT 0 COMMENT '排序顺序',
- menu_type ENUM('menu', 'button') DEFAULT 'menu' COMMENT '菜单类型',
- is_hidden BOOLEAN DEFAULT FALSE COMMENT '是否隐藏',
- is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
- description TEXT NULL COMMENT '菜单描述',
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- INDEX idx_parent_id (parent_id),
- INDEX idx_path (path),
- INDEX idx_sort_order (sort_order)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统菜单表'
- """)
-
- # 2. 角色表 - 存储用户角色
- print("👥 创建角色表 (roles)...")
- cursor.execute("""
- CREATE TABLE IF NOT EXISTS roles (
- id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
- name VARCHAR(50) NOT NULL UNIQUE COMMENT '角色名称',
- display_name VARCHAR(100) NOT NULL COMMENT '角色显示名称',
- description TEXT NULL COMMENT '角色描述',
- is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
- is_system BOOLEAN DEFAULT FALSE COMMENT '是否系统角色',
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- INDEX idx_name (name),
- INDEX idx_is_active (is_active)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色表'
- """)
-
- # 3. 权限表 - 存储系统权限
- print("🔐 创建权限表 (permissions)...")
- cursor.execute("""
- CREATE TABLE IF NOT EXISTS permissions (
- id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
- name VARCHAR(100) NOT NULL UNIQUE COMMENT '权限名称',
- display_name VARCHAR(100) NOT NULL COMMENT '权限显示名称',
- resource VARCHAR(100) NOT NULL COMMENT '资源标识',
- action VARCHAR(50) NOT NULL COMMENT '操作类型',
- description TEXT NULL COMMENT '权限描述',
- is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- INDEX idx_name (name),
- INDEX idx_resource_action (resource, action),
- UNIQUE KEY uk_resource_action (resource, action)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='权限表'
- """)
-
- # 4. 角色菜单关联表 - 角色可访问的菜单
- print("🔗 创建角色菜单关联表 (role_menus)...")
- cursor.execute("""
- CREATE TABLE IF NOT EXISTS role_menus (
- id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
- role_id CHAR(36) NOT NULL,
- menu_id CHAR(36) NOT NULL,
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- UNIQUE KEY uk_role_menu (role_id, menu_id),
- INDEX idx_role_id (role_id),
- INDEX idx_menu_id (menu_id)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色菜单关联表'
- """)
-
- # 5. 角色权限关联表 - 角色拥有的权限
- print("🔗 创建角色权限关联表 (role_permissions)...")
- cursor.execute("""
- CREATE TABLE IF NOT EXISTS role_permissions (
- id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
- role_id CHAR(36) NOT NULL,
- permission_id CHAR(36) NOT NULL,
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- UNIQUE KEY uk_role_permission (role_id, permission_id),
- INDEX idx_role_id (role_id),
- INDEX idx_permission_id (permission_id)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色权限关联表'
- """)
-
- # 6. 用户角色关联表 - 用户拥有的角色
- print("🔗 创建用户角色关联表 (user_roles)...")
- cursor.execute("""
- CREATE TABLE IF NOT EXISTS user_roles (
- id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
- user_id CHAR(36) NOT NULL,
- role_id CHAR(36) NOT NULL,
- assigned_by CHAR(36) NULL COMMENT '分配者ID',
- assigned_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- expires_at TIMESTAMP NULL COMMENT '过期时间',
- is_active BOOLEAN DEFAULT TRUE COMMENT '是否启用',
- created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- UNIQUE KEY uk_user_role (user_id, role_id),
- INDEX idx_user_id (user_id),
- INDEX idx_role_id (role_id),
- INDEX idx_expires_at (expires_at)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表'
- """)
-
- print("✅ 所有RBAC表创建成功")
-
- # 插入初始数据
- print("\n📝 插入初始数据...")
- insert_initial_data(cursor)
-
- conn.commit()
- cursor.close()
- conn.close()
-
- print("\n" + "=" * 60)
- print("🎉 RBAC权限管理系统初始化完成!")
- print("=" * 60)
-
- return True
-
- except Exception as e:
- print(f"❌ 创建表失败: {e}")
- conn.rollback()
- cursor.close()
- conn.close()
- return False
- def insert_initial_data(cursor):
- """插入初始数据"""
-
- # 1. 插入系统菜单
- print(" 📋 插入系统菜单...")
- menus_data = [
- # 主菜单
- ('dashboard-menu', None, 'dashboard', '仪表盘', '/dashboard', 'dashboard/Index', 'House', 1, 'menu', False),
- ('profile-menu', None, 'profile', '个人资料', '/profile', 'user/Profile', 'User', 2, 'menu', False),
- ('admin-menu', None, 'admin', '系统管理', '/admin', None, 'Setting', 3, 'menu', False),
-
- # 系统管理子菜单
- ('admin-dashboard-menu', 'admin-menu', 'admin-dashboard', '管理概览', '/admin/dashboard', 'admin/Dashboard', 'Monitor', 1, 'menu', False),
- ('admin-users-menu', 'admin-menu', 'admin-users', '用户管理', '/admin/users', 'admin/Users', 'UserFilled', 2, 'menu', False),
- ('admin-roles-menu', 'admin-menu', 'admin-roles', '角色管理', '/admin/roles', 'admin/Roles', 'Avatar', 3, 'menu', False),
- ('admin-menus-menu', 'admin-menu', 'admin-menus', '菜单管理', '/admin/menus', 'admin/Menus', 'Menu', 4, 'menu', False),
- ('admin-permissions-menu', 'admin-menu', 'admin-permissions', '权限管理', '/admin/permissions', 'admin/Permissions', 'Key', 5, 'menu', False),
- ('admin-apps-menu', 'admin-menu', 'admin-apps', '应用管理', '/admin/apps', 'admin/Apps', 'Grid', 6, 'menu', False),
- ('admin-logs-menu', 'admin-menu', 'admin-logs', '系统日志', '/admin/logs', 'admin/Logs', 'Document', 7, 'menu', False),
- ('admin-settings-menu', 'admin-menu', 'admin-settings', '系统设置', '/admin/settings', 'admin/Settings', 'Tools', 8, 'menu', False),
-
- # 应用管理按钮权限
- ('apps-create-btn', 'admin-apps-menu', 'apps-create', '创建应用', None, None, 'Plus', 1, 'button', False),
- ('apps-edit-btn', 'admin-apps-menu', 'apps-edit', '编辑应用', None, None, 'Edit', 2, 'button', False),
- ('apps-delete-btn', 'admin-apps-menu', 'apps-delete', '删除应用', None, None, 'Delete', 3, 'button', False),
- ('apps-secret-btn', 'admin-apps-menu', 'apps-secret', '查看密钥', None, None, 'Key', 4, 'button', False),
- ]
-
- # 先插入父菜单,再插入子菜单
- menu_id_map = {}
-
- for menu_data in menus_data:
- name, parent_name, key, title, path, component, icon, sort_order, menu_type, is_hidden = menu_data
- parent_id = menu_id_map.get(parent_name) if parent_name else None
-
- cursor.execute("""
- INSERT INTO menus (id, parent_id, name, title, path, component, icon, sort_order, menu_type, is_hidden)
- VALUES (UUID(), %s, %s, %s, %s, %s, %s, %s, %s, %s)
- """, (parent_id, key, title, path, component, icon, sort_order, menu_type, is_hidden))
-
- # 获取插入的菜单ID
- cursor.execute("SELECT id FROM menus WHERE name = %s ORDER BY created_at DESC LIMIT 1", (key,))
- menu_id = cursor.fetchone()[0]
- menu_id_map[name] = menu_id
-
- # 2. 插入系统角色
- print(" 👥 插入系统角色...")
- roles_data = [
- ('super_admin', '超级管理员', '拥有系统所有权限的超级管理员', True, True),
- ('admin', '管理员', '拥有大部分管理权限的管理员', True, True),
- ('user_manager', '用户管理员', '负责用户管理的管理员', True, False),
- ('app_manager', '应用管理员', '负责应用管理的管理员', True, False),
- ('user', '普通用户', '系统普通用户', True, True),
- ]
-
- role_id_map = {}
- for role_data in roles_data:
- name, display_name, description, is_active, is_system = role_data
- cursor.execute("""
- INSERT INTO roles (id, name, display_name, description, is_active, is_system)
- VALUES (UUID(), %s, %s, %s, %s, %s)
- """, (name, display_name, description, is_active, is_system))
-
- # 获取插入的角色ID
- cursor.execute("SELECT id FROM roles WHERE name = %s", (name,))
- role_id = cursor.fetchone()[0]
- role_id_map[name] = role_id
-
- # 3. 插入系统权限
- print(" 🔐 插入系统权限...")
- permissions_data = [
- # 用户管理权限
- ('user.view', '查看用户', 'user', 'view', '查看用户列表和详情'),
- ('user.create', '创建用户', 'user', 'create', '创建新用户'),
- ('user.edit', '编辑用户', 'user', 'edit', '编辑用户信息'),
- ('user.delete', '删除用户', 'user', 'delete', '删除用户'),
- ('user.assign_role', '分配角色', 'user', 'assign_role', '为用户分配角色'),
-
- # 角色管理权限
- ('role.view', '查看角色', 'role', 'view', '查看角色列表和详情'),
- ('role.create', '创建角色', 'role', 'create', '创建新角色'),
- ('role.edit', '编辑角色', 'role', 'edit', '编辑角色信息'),
- ('role.delete', '删除角色', 'role', 'delete', '删除角色'),
- ('role.assign_permission', '分配权限', 'role', 'assign_permission', '为角色分配权限'),
-
- # 菜单管理权限
- ('menu.view', '查看菜单', 'menu', 'view', '查看菜单列表和详情'),
- ('menu.create', '创建菜单', 'menu', 'create', '创建新菜单'),
- ('menu.edit', '编辑菜单', 'menu', 'edit', '编辑菜单信息'),
- ('menu.delete', '删除菜单', 'menu', 'delete', '删除菜单'),
-
- # 应用管理权限
- ('app.view', '查看应用', 'app', 'view', '查看应用列表和详情'),
- ('app.create', '创建应用', 'app', 'create', '创建新应用'),
- ('app.edit', '编辑应用', 'app', 'edit', '编辑应用信息'),
- ('app.delete', '删除应用', 'app', 'delete', '删除应用'),
- ('app.secret', '查看密钥', 'app', 'secret', '查看应用密钥'),
-
- # 系统管理权限
- ('system.view', '查看系统', 'system', 'view', '查看系统信息'),
- ('system.config', '系统配置', 'system', 'config', '修改系统配置'),
- ('system.log', '查看日志', 'system', 'log', '查看系统日志'),
- ]
-
- permission_id_map = {}
- for perm_data in permissions_data:
- name, display_name, resource, action, description = perm_data
- cursor.execute("""
- INSERT INTO permissions (id, name, display_name, resource, action, description)
- VALUES (UUID(), %s, %s, %s, %s, %s)
- """, (name, display_name, resource, action, description))
-
- # 获取插入的权限ID
- cursor.execute("SELECT id FROM permissions WHERE name = %s", (name,))
- permission_id = cursor.fetchone()[0]
- permission_id_map[name] = permission_id
-
- # 4. 分配角色菜单权限
- print(" 🔗 分配角色菜单权限...")
-
- # 超级管理员 - 所有菜单
- super_admin_id = role_id_map['super_admin']
- cursor.execute("SELECT id FROM menus")
- all_menu_ids = [row[0] for row in cursor.fetchall()]
-
- for menu_id in all_menu_ids:
- cursor.execute("""
- INSERT INTO role_menus (id, role_id, menu_id)
- VALUES (UUID(), %s, %s)
- """, (super_admin_id, menu_id))
-
- # 管理员 - 除了系统设置外的所有菜单
- admin_id = role_id_map['admin']
- cursor.execute("SELECT id FROM menus WHERE name != 'admin-settings'")
- admin_menu_ids = [row[0] for row in cursor.fetchall()]
-
- for menu_id in admin_menu_ids:
- cursor.execute("""
- INSERT INTO role_menus (id, role_id, menu_id)
- VALUES (UUID(), %s, %s)
- """, (admin_id, menu_id))
-
- # 普通用户 - 基础菜单
- user_id = role_id_map['user']
- basic_menus = ['dashboard', 'profile', 'apps']
- cursor.execute("SELECT id FROM menus WHERE name IN %s", (basic_menus,))
- user_menu_ids = [row[0] for row in cursor.fetchall()]
-
- for menu_id in user_menu_ids:
- cursor.execute("""
- INSERT INTO role_menus (id, role_id, menu_id)
- VALUES (UUID(), %s, %s)
- """, (user_id, menu_id))
-
- # 5. 分配角色权限
- print(" 🔗 分配角色权限...")
-
- # 超级管理员 - 所有权限
- for permission_id in permission_id_map.values():
- cursor.execute("""
- INSERT INTO role_permissions (id, role_id, permission_id)
- VALUES (UUID(), %s, %s)
- """, (super_admin_id, permission_id))
-
- # 管理员 - 除了系统配置外的权限
- admin_permissions = [p for p in permission_id_map.keys() if not p.startswith('system.config')]
- for perm_name in admin_permissions:
- cursor.execute("""
- INSERT INTO role_permissions (id, role_id, permission_id)
- VALUES (UUID(), %s, %s)
- """, (admin_id, permission_id_map[perm_name]))
-
- # 普通用户 - 基础权限
- user_permissions = ['app.view', 'app.create', 'app.edit', 'app.secret']
- for perm_name in user_permissions:
- cursor.execute("""
- INSERT INTO role_permissions (id, role_id, permission_id)
- VALUES (UUID(), %s, %s)
- """, (user_id, permission_id_map[perm_name]))
-
- # 6. 为现有admin用户分配超级管理员角色
- print(" 👤 为admin用户分配超级管理员角色...")
- cursor.execute("SELECT id FROM users WHERE username = 'admin'")
- admin_user = cursor.fetchone()
-
- if admin_user:
- admin_user_id = admin_user[0]
- cursor.execute("""
- INSERT INTO user_roles (id, user_id, role_id, assigned_by)
- VALUES (UUID(), %s, %s, %s)
- """, (admin_user_id, super_admin_id, admin_user_id))
- print(" ✅ admin用户已分配超级管理员角色")
- else:
- print(" ⚠️ 未找到admin用户")
-
- print(" ✅ 初始数据插入完成")
- if __name__ == "__main__":
- create_rbac_tables()
|