100 lines
2.3 KiB
PHP
100 lines
2.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Service;
|
|
|
|
use App\Model\User;
|
|
use Swoole\Table;
|
|
|
|
class ScopeTableManager
|
|
{
|
|
protected Table $table;
|
|
|
|
public function __construct(protected ScopeBitmapService $bitmapService)
|
|
{
|
|
$this->initTable();
|
|
}
|
|
|
|
/**
|
|
* 初始化 Swoole\Table
|
|
*/
|
|
protected function initTable(): void
|
|
{
|
|
$this->table = new Table(1024);
|
|
$this->table->column('role', Table::TYPE_STRING, 32);
|
|
$this->table->column('scope', Table::TYPE_STRING, 4096);
|
|
$this->table->column('version', Table::TYPE_INT, 8);
|
|
$this->table->create();
|
|
}
|
|
|
|
public function getTable(): Table
|
|
{
|
|
return $this->table;
|
|
}
|
|
|
|
/**
|
|
* 获取用户 scope 数据,未命中时懒加载
|
|
*
|
|
* @param int $user_id
|
|
* @return array{role: string, scope: string, version: int}|null
|
|
*/
|
|
public function getUserScope(int $user_id): ?array
|
|
{
|
|
$key = (string) $user_id;
|
|
$row = $this->table->get($key);
|
|
|
|
if ($row !== false) {
|
|
return $row;
|
|
}
|
|
|
|
// Table 未命中,从数据库加载
|
|
return $this->rebuildUserScope($user_id);
|
|
}
|
|
|
|
/**
|
|
* 重建用户 scope 并写入 Table
|
|
*
|
|
* @param int $user_id
|
|
* @return array{role: string, scope: string, version: int}|null
|
|
*/
|
|
public function rebuildUserScope(int $user_id): ?array
|
|
{
|
|
$user = User::query()->with('role')->find($user_id);
|
|
if (!$user || !$user->role) {
|
|
return null;
|
|
}
|
|
|
|
$role_name = $user->role->name;
|
|
|
|
// administrator 不需要 bitmap
|
|
if ($role_name === 'administrator') {
|
|
$bitmap = '';
|
|
} elseif ($role_name === 'developer') {
|
|
$bitmap = $this->bitmapService->buildForDeveloper($user_id);
|
|
} else {
|
|
$bitmap = $this->bitmapService->buildForUser($user_id);
|
|
}
|
|
|
|
$data = [
|
|
'role' => $role_name,
|
|
'scope' => $bitmap,
|
|
'version' => time(),
|
|
];
|
|
|
|
$this->table->set((string) $user_id, $data);
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* 清除用户 scope(权限变更时先清再重建)
|
|
*
|
|
* @param int $user_id
|
|
* @return void
|
|
*/
|
|
public function invalidateUser(int $user_id): void
|
|
{
|
|
$this->table->del((string) $user_id);
|
|
}
|
|
}
|