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

78 lines
2.5 KiB
PHP

<?php
/**
* 将已有角色权限升级为 目录/菜单/按钮 结构
* 若 roles 表不存在,会先自动执行角色/部门建表迁移。
*
* 用法: php database/migrate_permission_tree.php
*/
require __DIR__ . '/../vendor/autoload.php';
$app = new think\App();
$app->initialize();
use app\service\PermissionCatalog;
use think\facade\Db;
try {
$dbName = Db::getConfig('database') ?: env('DB_NAME', 'ai_chat');
$tableExists = function (string $table) use ($dbName) {
$rows = Db::query(
'SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? LIMIT 1',
[$dbName, $table]
);
return !empty($rows);
};
if (!$tableExists('roles') || !$tableExists('departments')) {
echo "roles/departments 表不存在,先执行 migrate_roles_departments.php ...\n";
$cmd = 'php ' . escapeshellarg(__DIR__ . DIRECTORY_SEPARATOR . 'migrate_roles_departments.php');
passthru($cmd, $code);
if ($code !== 0) {
throw new RuntimeException('migrate_roles_departments.php 执行失败');
}
}
if (!$tableExists('roles')) {
throw new RuntimeException('roles 表仍不存在,请检查数据库连接');
}
$roles = Db::name('roles')->select();
if (!$roles || count($roles) === 0) {
echo "roles 表为空,跳过权限升级。\n";
exit(0);
}
foreach ($roles as $role) {
$raw = $role['permissions'] ?? '{}';
$perms = is_string($raw) ? json_decode($raw, true) : $raw;
if (!is_array($perms)) {
$perms = [];
}
if (($role['slug'] ?? '') === 'super_admin') {
$normalized = PermissionCatalog::fullPermissions();
} elseif (($role['slug'] ?? '') === 'dept_manager') {
$normalized = PermissionCatalog::normalize([
'can_access_admin' => true,
'dirs' => ['dir:overview', 'dir:business'],
'menus' => ['menu:dashboard', 'menu:conversations'],
'buttons' => ['btn:conv:view_subordinate'],
]);
} else {
$normalized = PermissionCatalog::normalize($perms);
}
Db::name('roles')->where('id', $role['id'])->update([
'permissions' => json_encode($normalized, JSON_UNESCAPED_UNICODE),
]);
echo "Updated role: {$role['name']}\n";
}
echo "Permission tree migration completed.\n";
} catch (\Throwable $e) {
echo 'Error: ' . $e->getMessage() . "\n";
exit(1);
}