Files
chat/backend/database/migrate_sys_permissions.php
T
2026-07-22 10:18:59 +08:00

184 lines
7.1 KiB
PHP

<?php
/**
* 系统权限节点表(目录/菜单/按钮)
* 用法: php database/migrate_sys_permissions.php
*/
require __DIR__ . '/../vendor/autoload.php';
$app = new think\App();
$app->initialize();
use app\service\PermissionCatalog;
use think\facade\Db;
function tableExists(string $table): bool
{
$db = Db::getConfig('database') ?: env('DB_NAME', 'ai_chat');
$rows = Db::query(
'SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? LIMIT 1',
[$db, $table]
);
return !empty($rows);
}
function seedNode(array $node, ?int $parentId = null, int $sort = 0): int
{
$existing = Db::name('sys_permissions')->where('code', $node['code'])->find();
if ($existing) {
return (int) $existing['id'];
}
return (int) Db::name('sys_permissions')->insertGetId([
'type' => $node['type'],
'code' => $node['code'],
'name' => $node['name'],
'parent_id' => $parentId,
'path' => $node['path'] ?? null,
'icon' => $node['icon'] ?? null,
'sort_order' => $node['sort_order'] ?? $sort,
'is_system' => $node['is_system'] ?? 1,
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
]);
}
try {
if (!tableExists('sys_permissions')) {
Db::execute("CREATE TABLE sys_permissions (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
type ENUM('dir','menu','btn') NOT NULL,
code VARCHAR(100) NOT NULL UNIQUE,
name VARCHAR(100) NOT NULL,
parent_id INT UNSIGNED NULL,
path VARCHAR(200) NULL,
icon VARCHAR(50) NULL,
sort_order INT DEFAULT 0,
is_system TINYINT(1) DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_parent (parent_id),
INDEX idx_type (type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
echo "Created table sys_permissions\n";
}
$builtin = PermissionCatalog::builtinTree();
// 补齐:权限管理菜单 + 用户增删按钮
foreach ($builtin as &$dir) {
if ($dir['code'] === 'dir:org') {
foreach ($dir['children'] as &$menu) {
if ($menu['code'] === 'menu:users') {
$codes = array_column($menu['children'], 'code');
if (!in_array('btn:user:create', $codes, true)) {
array_unshift($menu['children'], ['code' => 'btn:user:create', 'name' => '新增用户', 'type' => 'btn']);
}
if (!in_array('btn:user:delete', $codes, true)) {
$menu['children'][] = ['code' => 'btn:user:delete', 'name' => '删除用户', 'type' => 'btn'];
}
}
}
unset($menu);
}
if ($dir['code'] === 'dir:system') {
$menuCodes = array_column($dir['children'], 'code');
if (!in_array('menu:permissions', $menuCodes, true)) {
$dir['children'][] = [
'code' => 'menu:permissions',
'name' => '权限管理',
'type' => 'menu',
'path' => '/permissions',
'icon' => '🔑',
'children' => [
['code' => 'btn:perm:create', 'name' => '新增权限', 'type' => 'btn'],
['code' => 'btn:perm:edit', 'name' => '编辑权限', 'type' => 'btn'],
['code' => 'btn:perm:delete', 'name' => '删除权限', 'type' => 'btn'],
],
];
}
}
}
unset($dir);
$count = (int) Db::name('sys_permissions')->count();
if ($count === 0) {
$sortDir = 0;
foreach ($builtin as $dir) {
$dirId = seedNode($dir, null, $sortDir++);
$sortMenu = 0;
foreach ($dir['children'] ?? [] as $menu) {
$menuId = seedNode($menu, $dirId, $sortMenu++);
$sortBtn = 0;
foreach ($menu['children'] ?? [] as $btn) {
seedNode($btn, $menuId, $sortBtn++);
}
}
}
echo "Seeded builtin permissions\n";
} else {
// 增量补种新增节点
$extra = [
['type' => 'btn', 'code' => 'btn:user:create', 'name' => '新增用户', 'parent_code' => 'menu:users'],
['type' => 'btn', 'code' => 'btn:user:delete', 'name' => '删除用户', 'parent_code' => 'menu:users'],
['type' => 'menu', 'code' => 'menu:permissions', 'name' => '权限管理', 'parent_code' => 'dir:system', 'path' => '/permissions', 'icon' => '🔑'],
['type' => 'btn', 'code' => 'btn:perm:create', 'name' => '新增权限', 'parent_code' => 'menu:permissions'],
['type' => 'btn', 'code' => 'btn:perm:edit', 'name' => '编辑权限', 'parent_code' => 'menu:permissions'],
['type' => 'btn', 'code' => 'btn:perm:delete', 'name' => '删除权限', 'parent_code' => 'menu:permissions'],
];
foreach ($extra as $item) {
if (Db::name('sys_permissions')->where('code', $item['code'])->find()) {
continue;
}
$parent = Db::name('sys_permissions')->where('code', $item['parent_code'])->find();
if (!$parent && $item['code'] === 'btn:perm:create') {
continue;
}
// 若菜单还不存在,先建菜单
if ($item['code'] === 'menu:permissions' && $parent) {
seedNode([
'type' => 'menu',
'code' => 'menu:permissions',
'name' => '权限管理',
'path' => '/permissions',
'icon' => '🔑',
'is_system' => 1,
], (int) $parent['id']);
continue;
}
if (!$parent) {
if ($item['parent_code'] === 'menu:permissions') {
$parent = Db::name('sys_permissions')->where('code', 'menu:permissions')->find();
}
}
if (!$parent) {
continue;
}
seedNode([
'type' => $item['type'],
'code' => $item['code'],
'name' => $item['name'],
'path' => $item['path'] ?? null,
'icon' => $item['icon'] ?? null,
'is_system' => 1,
], (int) $parent['id']);
echo "Added {$item['code']}\n";
}
}
// 超级管理员补齐全部权限码
if (tableExists('roles')) {
$full = PermissionCatalog::fullPermissions();
Db::name('roles')->where('slug', 'super_admin')->update([
'permissions' => json_encode($full, JSON_UNESCAPED_UNICODE),
]);
echo "Updated super_admin permissions\n";
}
echo "Migration completed.\n";
} catch (\Throwable $e) {
echo 'Error: ' . $e->getMessage() . "\n";
exit(1);
}