Skip to content

Commit

Permalink
feat: implement data permission management with DataScope and related…
Browse files Browse the repository at this point in the history
… aspects
  • Loading branch information
zds-s committed Mar 11, 2025
1 parent d60baff commit c41a31b
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 0 deletions.
81 changes: 81 additions & 0 deletions app/Library/DataPermission/Aspects/DataScopeAspect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace App\Library\DataPermission\Aspects;

use App\Library\DataPermission\Attribute\DataScope;
use Hyperf\Context\Context;
use Hyperf\Database\Query\Builder;
use Hyperf\Di\Annotation\Aspect;
use Hyperf\Di\Aop\AbstractAspect;
use Hyperf\Di\Aop\ProceedingJoinPoint;

#[Aspect]
final class DataScopeAspect extends AbstractAspect
{

public const CONTEXT_KEY = 'data_permission';

public array $annotations = [
DataScope::class
];

public array $classes = [
Builder::class.'::update',
Builder::class.'::delete',
Builder::class.'::runSelect',
];

public function process(ProceedingJoinPoint $proceedingJoinPoint)
{
if (
isset($proceedingJoinPoint->getAnnotationMetadata()->class[DataScope::class]) ||
isset($proceedingJoinPoint->getAnnotationMetadata()->method[DataScope::class])
){
return $this->handleDataScope($proceedingJoinPoint);
}

if ($proceedingJoinPoint->className === Builder::class){
if ($proceedingJoinPoint->methodName==='runSelect'){
return $this->handleSelect($proceedingJoinPoint);
}
if ($proceedingJoinPoint->methodName==='delete'){
return $this->handleDelete($proceedingJoinPoint);
}
if ($proceedingJoinPoint->methodName==='update'){
return $this->handleUpdate($proceedingJoinPoint);
}
}
return $proceedingJoinPoint->process();
}

protected function handleDelete(ProceedingJoinPoint $proceedingJoinPoint)
{
return $proceedingJoinPoint->process();
}

protected function handleUpdate(ProceedingJoinPoint $proceedingJoinPoint)
{
return $proceedingJoinPoint->process();
}

protected function handleSelect(ProceedingJoinPoint $proceedingJoinPoint)
{
/**
* @var Builder $builder
*/
$builder = $proceedingJoinPoint->getInstance();
if (Context::has(self::CONTEXT_KEY)){
// todo 做数据权限处理
}
return $proceedingJoinPoint->process();
}


protected function handleDataScope(ProceedingJoinPoint $proceedingJoinPoint)
{
Context::set(self::CONTEXT_KEY, 1);
$result = $proceedingJoinPoint->process();
Context::destroy(self::CONTEXT_KEY);
return $result;
}
}
12 changes: 12 additions & 0 deletions app/Library/DataPermission/Attribute/DataScope.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace App\Library\DataPermission\Attribute;

use Attribute;
use Hyperf\Di\Annotation\AbstractAnnotation;

#[Attribute(Attribute::TARGET_CLASS|Attribute::TARGET_METHOD)]
final class DataScope extends AbstractAnnotation
{

}
8 changes: 8 additions & 0 deletions app/Library/DataPermission/Manager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace App\Library\DataPermission;

final class Manager
{

}
26 changes: 26 additions & 0 deletions app/Library/DataPermission/Scope/DataScope.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Library\DataPermission\Scope;

use App\Http\CurrentUser;
use Hyperf\Database\Model\Builder;
use Hyperf\Database\Model\Model;
use Hyperf\Database\Model\Scope;

final class DataScope implements Scope
{
public function __construct(
private readonly CurrentUser $currentUser
){}

public function apply(Builder $builder, Model $model): void
{
if ($this->currentUser->user() === null){
return;
}
$user = $this->currentUser->user();
if ($user->isSuperAdmin()){
return;
}
}
}
23 changes: 23 additions & 0 deletions app/Model/Permission/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,27 @@ public function position(): BelongsToMany
{
return $this->belongsToMany(Position::class, 'user_position', 'user_id', 'position_id');
}

public function getPolicy(): Policy|null
{
/**
* @var Policy|null $policy
*/
$policy = $this->policy()->first();
if (!empty($policy)){
return $policy;
}

$this->load('roles');
$roleList = $this->roles;
foreach ($roleList as $role){
$current = $role->policy()->first();
if (!empty($current)){
return $current;
}
}

return null;

}
}

0 comments on commit c41a31b

Please sign in to comment.