初始化本地仓库
This commit is contained in:
@@ -0,0 +1,345 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
*+------------------
|
||||
* madong
|
||||
*+------------------
|
||||
* Copyright (c) https://gitee.com/motion-code All rights reserved.
|
||||
*+------------------
|
||||
* Author: Mr. April (405784684@qq.com)
|
||||
*+------------------
|
||||
* Official Website: http://www.madong.tech
|
||||
*/
|
||||
|
||||
namespace app\service\admin\system;
|
||||
|
||||
use app\dao\system\RoleDao;
|
||||
use app\model\system\Role;
|
||||
use core\base\BaseService;
|
||||
use core\exception\handler\AdminException;
|
||||
use madong\helper\Arr;
|
||||
use madong\helper\PropertyCopier;
|
||||
use support\Container;
|
||||
|
||||
class RoleService extends BaseService
|
||||
{
|
||||
|
||||
/**
|
||||
* 缓存key
|
||||
*/
|
||||
const CACHE_ALL_ROLES_DATA = 'roles_all_data';
|
||||
|
||||
public function __construct(RoleDao $dao)
|
||||
{
|
||||
$this->dao = $dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的角色
|
||||
*
|
||||
* @param array $where
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getAllRoles(array $where = []): array
|
||||
{
|
||||
// 1. 优先从缓存获取所有角色数据
|
||||
$allRoles = $this->cacheDriver()->remember(
|
||||
self::CACHE_ALL_ROLES_DATA, // 缓存键名
|
||||
function () {
|
||||
$results = $this->dao->getModel()
|
||||
->where('enabled', 1)
|
||||
->orderBy('sort', 'asc')
|
||||
->get(["id",
|
||||
"pid",
|
||||
"name",
|
||||
"code",
|
||||
"is_super_admin",
|
||||
"role_type",
|
||||
"data_scope",
|
||||
"enabled",
|
||||
"sort"]);
|
||||
|
||||
return $results->toArray();
|
||||
}
|
||||
);
|
||||
// 2.$where 条件筛数据
|
||||
return Arr::filterByWhere($allRoles, $where);
|
||||
}
|
||||
|
||||
/**
|
||||
* 传入角色id获取权限
|
||||
*
|
||||
* @param array $where
|
||||
* @param string $mode merge|unique
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getPermissions(array $where = [], string $mode = 'merge'): array
|
||||
{
|
||||
// 1. 优先从缓存获取所有全量角色数据
|
||||
$data = $this->cacheDriver()->remember(
|
||||
self::CACHE_ALL_ROLES_DATA, // 缓存键名
|
||||
function () {
|
||||
return $this->dao->getRolePermissions();
|
||||
}
|
||||
);
|
||||
//2. 条件过滤
|
||||
$result = Arr::filterByWhere($data, $where);
|
||||
if ($mode == 'unique') {
|
||||
return $result['menu'] ?? [];
|
||||
}
|
||||
return [
|
||||
'menu' => array_merge([], ...array_column($result, 'menu')),
|
||||
'api' => array_merge([], ...array_column($result, 'api')),
|
||||
'button' => array_merge([], ...array_column($result, 'button')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过角色id 获取菜单权限IDS
|
||||
*
|
||||
* @param int|string $id
|
||||
* @param string|null $tenantId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPermissionColumns(int|string $id, string|null $tenantId = null): array
|
||||
{
|
||||
$role = $this->dao->get($id);
|
||||
if (!$role) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 通过关联关系获取菜单ID
|
||||
return $role->menus()->pluck('id')->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* save
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return Role|null
|
||||
* @throws \core\exception\handler\AdminException
|
||||
*/
|
||||
public function save(array $data): Role|null
|
||||
{
|
||||
try {
|
||||
return $this->transaction(function () use ($data) {
|
||||
$model = $this->dao->save($data);
|
||||
$handlePermissions = isset($data['permissions']) && $data['permissions'] !== null;
|
||||
|
||||
// 有传权限key,才处理权限
|
||||
if ($handlePermissions) {
|
||||
$menus = $data['permissions'];
|
||||
// 同步角色菜单关联
|
||||
$model->menus()->sync($menus);
|
||||
|
||||
// 清理相关用户的权限缓存
|
||||
$this->clearUserPermissionCacheByRole($model->id);
|
||||
}
|
||||
return $model;
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
throw new AdminException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param $id
|
||||
* @param $data
|
||||
*
|
||||
* @return void
|
||||
* @throws \core\exception\handler\AdminException
|
||||
*/
|
||||
// public function update($id, $data): void
|
||||
// {
|
||||
// try {
|
||||
// $this->transaction(function () use ($id, $data) {
|
||||
// // 获取传入的权限列表(如果存在)
|
||||
// $menus = $data['permissions'] ?? [];
|
||||
// // 从数据访问对象中获取模型实例
|
||||
// $model = $this->dao->get($id);
|
||||
// if (!$model) {
|
||||
// return;
|
||||
// }
|
||||
// // 使用属性复制器将传入的数据复制到模型中
|
||||
// PropertyCopier::copyProperties((object)$data, $model);
|
||||
// $model->save();
|
||||
//
|
||||
// // 格式化用户标识符,用于 Casbin
|
||||
// $roleId = PolicyPrefix::ROLE->value . strval($model->id);
|
||||
// $domain = '*';
|
||||
//
|
||||
// // 获取当前用户在 Casbin 中的隐式资源权限
|
||||
// $currentPolicies = Permission::getImplicitResourcesForUser($roleId, $domain);
|
||||
//
|
||||
// // 提取完整的当前权限(0-5)
|
||||
// $currentPermissions = array_map(
|
||||
// function ($policy) {
|
||||
// return $policy; // 保留完整的策略数组
|
||||
// },
|
||||
// $currentPolicies
|
||||
// );
|
||||
//
|
||||
// // 将传入的菜单数据转换为 Casbin 策略格式
|
||||
// $menuService = new SysMenuService();
|
||||
// $policyService = new SysCasbinService();
|
||||
//
|
||||
// $menusData = $menuService->getAllMenus(['id' => $menus], 'menu', false);
|
||||
// // 构建传入的权限列表,格式与当前权限相同
|
||||
// $incomingPolicies = [];
|
||||
// foreach ($menusData as $item) {
|
||||
// $path = $policyService->resolvePermissionIdentifier($item);
|
||||
// // 构建策略数组
|
||||
// $policy = [
|
||||
// $roleId, // sub
|
||||
// $domain, // dom
|
||||
// $path, // obj
|
||||
// '*', // act(根据你的业务需求调整)
|
||||
// $item['methods'], // method
|
||||
// PolicyPrefix::MENU->value . $item['id'], // trace_id 资源归属用于追踪
|
||||
// ];
|
||||
// // 保留完整的策略数组
|
||||
// $incomingPolicies[] = $policy;
|
||||
// }
|
||||
// // 更新 Casbin 权限
|
||||
// $policyService->updateCasbinPolicies($currentPermissions, $incomingPolicies);
|
||||
// // 同步 Casbin 权限,确保只有授权角色保留
|
||||
// $model->casbin()->sync([$roleId]);
|
||||
// });
|
||||
// } catch (\Throwable $e) {
|
||||
// // 捕获异常并抛出自定义异常
|
||||
// throw new AdminException($e->getMessage());
|
||||
// }
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
*
|
||||
* @param $id
|
||||
* @param $data
|
||||
*
|
||||
* @return void
|
||||
* @throws \core\exception\handler\AdminException
|
||||
*/
|
||||
public function update($id, $data): void
|
||||
{
|
||||
try {
|
||||
$this->transaction(function () use ($id, $data) {
|
||||
$model = $this->dao->get($id);
|
||||
if (!$model) {
|
||||
return;
|
||||
}
|
||||
|
||||
PropertyCopier::copyProperties((object)$data, $model);
|
||||
$model->save();
|
||||
|
||||
// 检查 permissions 是否存在且不为 null(未定义或显式 null 时不处理权限)
|
||||
$handlePermissions = isset($data['permissions']) && $data['permissions'] !== null;
|
||||
if ($handlePermissions) {
|
||||
$menus = $data['permissions']; // 获取权限列表
|
||||
|
||||
// 同步角色菜单关联
|
||||
$model->menus()->sync($menus);
|
||||
|
||||
// 清理相关用户的权限缓存
|
||||
$this->clearUserPermissionCacheByRole($model->id);
|
||||
}
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
// 捕获异常并抛出自定义异常
|
||||
throw new AdminException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除角色
|
||||
*
|
||||
* @param array $id
|
||||
* @param bool $force
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \core\exception\handler\AdminException
|
||||
*/
|
||||
public function destroy(array $id, bool $force = false): mixed
|
||||
{
|
||||
try {
|
||||
return $this->transaction(function () use ($id, $force) {
|
||||
$data = Arr::normalize($id);
|
||||
$deletedIds = [];
|
||||
|
||||
foreach ($data as $id) {
|
||||
$item = $this->get($id);
|
||||
if ($item) {
|
||||
$primaryKey = $item->getPk();
|
||||
|
||||
// 清理相关用户的权限缓存
|
||||
$this->clearUserPermissionCacheByRole($id);
|
||||
|
||||
$item->delete();
|
||||
$deletedIds[] = $item->{$primaryKey};
|
||||
}
|
||||
}
|
||||
return $deletedIds;
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
throw new AdminException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配数据权限
|
||||
*
|
||||
* @param $id
|
||||
* @param $data
|
||||
*
|
||||
* @throws \core\exception\handler\AdminException
|
||||
*/
|
||||
public function updateScope($id, $data): void
|
||||
{
|
||||
try {
|
||||
$this->transaction(function () use ($id, $data) {
|
||||
$scope = $data['scopes'] ?? [];
|
||||
$model = $this->dao->get($id);
|
||||
PropertyCopier::copyProperties((object)$data, $model);
|
||||
if (!empty($model)) {
|
||||
$model->save();
|
||||
if ($model->data_scope !== 2) {
|
||||
$scope = [];
|
||||
}
|
||||
$model->scopes()->sync($scope);
|
||||
}
|
||||
$this->cacheDriver()->delete(self::CACHE_ALL_ROLES_DATA);
|
||||
});
|
||||
} catch (\Throwable $e) {
|
||||
throw new AdminException($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理角色的用户权限缓存
|
||||
*
|
||||
* @param int|string $roleId
|
||||
*/
|
||||
private function clearUserPermissionCacheByRole(int|string $roleId): void
|
||||
{
|
||||
// 获取拥有此角色的所有用户
|
||||
/** @var AdminRoleService $adminRoleService */
|
||||
$adminRoleService = Container::make(AdminRoleService::class);
|
||||
$userIds = $adminRoleService->getUserIdsByRoleId($roleId);
|
||||
|
||||
if (!empty($userIds)) {
|
||||
// 清理每个用户的权限缓存
|
||||
foreach ($userIds as $userId) {
|
||||
$cacheKey = 'user_permissions_' . $userId;
|
||||
$this->cacheDriver()->delete($cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user