MineAdmin 交流群

官方QQ群: 150105478

Skip to content

使用示例

在代碼中使用數據權限、目前支持多種方式進行動態開啓與關閉。 以下舉幾種常見的開發案例

對整個模型進行數據權限控制

以默認的 User 模型為例,假設我們需要對 User 模型進行數據權限控制。

可以在 User 模型中 use DataScopes trait 來啓用數據權限作用域。

php

use App\Library\DataPermission\Scope\DataScopes;

class User {}
    // 使用數據權限作用域
    use DataScopes;

    // 其他代碼...
}

這樣會使所有對 User 模型的查詢都自動應用數據權限控制。

對某個代碼塊進行數據權限控制

得益於 Hyperf Aop 特性,我們可以在類或者類方法上使用 DataScope 註解來對指定的代碼塊開啓數據權限控制。

以自帶的用户模塊的分頁列表為例

php

class UserService
{
    #[DataScope(
        scopeType: ScopeType::CREATED_BY,
        onlyTables: ['user']
    )]
    public function page(array $params, int $page = 1, int $pageSize = 10): array
    {
        return parent::page($params, $page, $pageSize); // TODO: Change the autogenerated stub
    }
}

這樣在調用 page 方法時,數據權限會自動應用到查詢中。

對指定的 ORM Query 進行權限控制

在某些特定場景中,需要更加細化的進行權限隔離。此時可以通過 Factory::make()->build() 方法來對指定的 Query 進行限制

php

use App\Library\DataPermission\Factory;
use App\Model\Permission\User;
use App\Model\Permission\Wallet;

class DemoService {

    public function test(User $user): void{
        $walletQuery = Wallet::query();
        // 對 WalletQuery 單獨進行數據隔離拼接
        Factory::make()->build($user,$walletQuery->getQuery());
    }
}

指定其他字段作為隔離條件

在某些情況下,業務表中可能會與默認的 created_by dept_id 字段名稱不一致,或者在某些複雜 join 查詢中。表名經過 table as xxxx 類似的操作。這個時候就需要指定新的隔離字段了。以下舉幾個例子方便理解在不同的使用方法中如何指定新的字段

在使用註解隔離某個方法的時候

自帶的 DataScope 註解有一些參數可以很方便的我們指定新的字段

php
<?php

declare(strict_types=1);
/**
 * This file is part of MineAdmin.
 *
 * @link     https://www.mineadmin.com
 * @document https://doc.mineadmin.com
 * @contact  root@imoi.cn
 * @license  https://github.com/mineadmin/MineAdmin/blob/master/LICENSE
 */

namespace App\Library\DataPermission\Attribute;

use App\Library\DataPermission\ScopeType;
use Hyperf\Di\Annotation\AbstractAnnotation;

#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
final class DataScope extends AbstractAnnotation
{
    public function __construct(
        // 指定部門字段名稱
        private readonly string $deptColumn = 'dept_id',
        // 創建人字段名稱
        private readonly string $createdByColumn = 'created_by',
        // 隔離方式
        private readonly ScopeType $scopeType = ScopeType::DEPT_CREATED_BY,
        // 只對指定的表進行隔離。為空則全部隔離
        private readonly ?array $onlyTables = null
    ) {}

    public function getOnlyTables(): ?array
    {
        return $this->onlyTables;
    }

    public function getDeptColumn(): string
    {
        return $this->deptColumn;
    }

    public function getCreatedByColumn(): string
    {
        return $this->createdByColumn;
    }

    public function getScopeType(): ScopeType
    {
        return $this->scopeType;
    }
}

在手動使用 Factory::make()->build

而在手動調用 Factory 實例進行條件拼接的時候。就需要使用 App\Library\DataPermission\Context 來進行配置了。

php

use App\Library\DataPermission\Context as Ctx;
use App\Library\DataPermission\Factory;

// 只對 sss 表進行數據隔離
Ctx::setOnlyTables(['sss']);
// 設置部門字段名稱
Ctx::setDeptColumn('department_id');
// 設置創建人字段名稱
Ctx::setCreatedByColumn('creator');
// 設置隔離方式
Ctx::setScopeType(ScopeType::DEPT_CREATED_BY);

$query = XXXModel::query();

Factory::make()->build($user,$query->getQuery());

WARNING

需要注意,不管哪種使用方式。如果新開一個協程。都要重新設置一遍才能起效

致力于为品牌和企业创造价值