1.将部门修改为渠道,并且所有dice_表关联渠道表
2.将所有配置表,记录表设置关联渠道 3.优化后台页面设置
This commit is contained in:
@@ -6,121 +6,133 @@
|
||||
// +----------------------------------------------------------------------
|
||||
namespace plugin\saiadmin\app\logic\system;
|
||||
|
||||
use app\dice\helper\AdminScopeHelper;
|
||||
use plugin\saiadmin\app\cache\UserMenuCache;
|
||||
use plugin\saiadmin\app\model\system\SystemRole;
|
||||
use plugin\saiadmin\app\service\SystemRoleChannelService;
|
||||
use plugin\saiadmin\basic\think\BaseLogic;
|
||||
use plugin\saiadmin\exception\ApiException;
|
||||
use plugin\saiadmin\utils\Helper;
|
||||
use support\think\Cache;
|
||||
use support\think\Db;
|
||||
|
||||
/**
|
||||
* 角色逻辑层
|
||||
* 角色逻辑层(按渠道 dept_id 隔离)
|
||||
*/
|
||||
class SystemRoleLogic extends BaseLogic
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->model = new SystemRole();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
* 分页列表(按渠道过滤)
|
||||
*/
|
||||
public function indexList(array $where, $requestDeptId = null): array
|
||||
{
|
||||
$query = $this->search($where);
|
||||
$this->applyDeptScope($query, $requestDeptId);
|
||||
$levelArr = array_column($this->adminInfo['roleList'] ?? [], 'level');
|
||||
if (!empty($levelArr)) {
|
||||
$maxLevel = max($levelArr);
|
||||
$query->where('level', '<', $maxLevel);
|
||||
}
|
||||
$query->where('id', '<>', SystemRoleChannelService::SUPER_ADMIN_ROLE_ID);
|
||||
return $this->getList($query);
|
||||
}
|
||||
|
||||
public function add($data): bool
|
||||
{
|
||||
$data = $this->handleData($data);
|
||||
$deptId = AdminScopeHelper::normalizeRecordDeptId($data['dept_id'] ?? null);
|
||||
$data['dept_id'] = $deptId;
|
||||
$this->assertCodeUniqueInDept($data['code'] ?? '', $deptId, null);
|
||||
return $this->model->save($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改数据
|
||||
*/
|
||||
public function edit($id, $data): bool
|
||||
{
|
||||
$model = $this->model->findOrEmpty($id);
|
||||
if ($model->isEmpty()) {
|
||||
throw new ApiException('Data not found');
|
||||
}
|
||||
$this->assertRoleWritable($model);
|
||||
$data = $this->handleData($data);
|
||||
$deptId = AdminScopeHelper::normalizeRecordDeptId($model->dept_id ?? $data['dept_id'] ?? null);
|
||||
$data['dept_id'] = $deptId;
|
||||
$this->assertCodeUniqueInDept($data['code'] ?? '', $deptId, (int) $id);
|
||||
return $model->save($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
public function destroy($ids): bool
|
||||
{
|
||||
// 越权保护
|
||||
$levelArr = array_column($this->adminInfo['roleList'], 'level');
|
||||
$maxLevel = max($levelArr);
|
||||
$levelArr = array_column($this->adminInfo['roleList'] ?? [], 'level');
|
||||
$maxLevel = !empty($levelArr) ? max($levelArr) : 100;
|
||||
|
||||
$num = SystemRole::where('level', '>=', $maxLevel)->whereIn('id', $ids)->count();
|
||||
if ($num > 0) {
|
||||
throw new ApiException('Cannot operate roles with higher level than current account');
|
||||
} else {
|
||||
return $this->model->destroy($ids);
|
||||
$idList = is_array($ids) ? $ids : explode(',', (string) $ids);
|
||||
foreach ($idList as $roleId) {
|
||||
$roleId = (int) $roleId;
|
||||
if ($roleId === SystemRoleChannelService::SUPER_ADMIN_ROLE_ID) {
|
||||
throw new ApiException('Cannot delete super admin role');
|
||||
}
|
||||
$role = $this->model->find($roleId);
|
||||
if (!$role) {
|
||||
continue;
|
||||
}
|
||||
$this->assertRoleWritable($role);
|
||||
if ((int) ($role->level ?? 0) >= $maxLevel) {
|
||||
throw new ApiException('Cannot operate roles with higher level than current account');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->model->destroy($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据处理
|
||||
*/
|
||||
protected function handleData($data)
|
||||
{
|
||||
// 越权保护
|
||||
$levelArr = array_column($this->adminInfo['roleList'], 'level');
|
||||
$maxLevel = max($levelArr);
|
||||
if ($data['level'] >= $maxLevel) {
|
||||
throw new ApiException('Cannot operate roles with higher level than current account');
|
||||
$levelArr = array_column($this->adminInfo['roleList'] ?? [], 'level');
|
||||
if (!empty($levelArr)) {
|
||||
$maxLevel = max($levelArr);
|
||||
if (($data['level'] ?? 0) >= $maxLevel) {
|
||||
throw new ApiException('Cannot operate roles with higher level than current account');
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 可操作角色
|
||||
* @param array $where
|
||||
* @return array
|
||||
*/
|
||||
public function accessRole(array $where = []): array
|
||||
public function accessRole(array $where = [], $requestDeptId = null): array
|
||||
{
|
||||
$query = $this->search($where);
|
||||
// 越权保护
|
||||
$levelArr = array_column($this->adminInfo['roleList'], 'level');
|
||||
$maxLevel = max($levelArr);
|
||||
$query->where('level', '<', $maxLevel);
|
||||
$this->applyDeptScope($query, $requestDeptId);
|
||||
$levelArr = array_column($this->adminInfo['roleList'] ?? [], 'level');
|
||||
if (!empty($levelArr)) {
|
||||
$maxLevel = max($levelArr);
|
||||
$query->where('level', '<', $maxLevel);
|
||||
}
|
||||
$query->where('id', '<>', SystemRoleChannelService::SUPER_ADMIN_ROLE_ID);
|
||||
$query->order('sort', 'desc');
|
||||
return $this->getAll($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色数组获取菜单
|
||||
* @param $ids
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuIdsByRoleIds($ids): array
|
||||
{
|
||||
if (empty($ids))
|
||||
if (empty($ids)) {
|
||||
return [];
|
||||
}
|
||||
return $this->model->where('id', 'in', $ids)->with([
|
||||
'menus' => function ($query) {
|
||||
$query->where('status', 1)->order('sort', 'desc');
|
||||
}
|
||||
])->select()->toArray();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色获取菜单
|
||||
* @param $id
|
||||
* @return array
|
||||
*/
|
||||
public function getMenuByRole($id): array
|
||||
{
|
||||
$role = $this->model->findOrEmpty($id);
|
||||
if ($role->isEmpty()) {
|
||||
throw new ApiException('Data not found');
|
||||
}
|
||||
$this->assertRoleWritable($role);
|
||||
$menus = $role->menus ?: [];
|
||||
return [
|
||||
'id' => $id,
|
||||
@@ -128,14 +140,14 @@ class SystemRoleLogic extends BaseLogic
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存菜单权限
|
||||
* @param $id
|
||||
* @param $menu_ids
|
||||
* @return mixed
|
||||
*/
|
||||
public function saveMenuPermission($id, $menu_ids): mixed
|
||||
{
|
||||
$role = $this->model->findOrEmpty($id);
|
||||
if ($role->isEmpty()) {
|
||||
throw new ApiException('Data not found');
|
||||
}
|
||||
$this->assertRoleWritable($role);
|
||||
|
||||
return $this->transaction(function () use ($id, $menu_ids) {
|
||||
$role = $this->model->findOrEmpty($id);
|
||||
if ($role) {
|
||||
@@ -147,10 +159,90 @@ class SystemRoleLogic extends BaseLogic
|
||||
}
|
||||
$cache = config('plugin.saiadmin.saithink.button_cache');
|
||||
$tag = $cache['role'] . $id;
|
||||
Cache::tag($tag)->clear(); // 清理权限缓存-角色TAG
|
||||
UserMenuCache::clearMenuCache(); // 清理菜单缓存
|
||||
Cache::tag($tag)->clear();
|
||||
UserMenuCache::clearMenuCache();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析并校验当前请求应操作的渠道 ID
|
||||
*/
|
||||
public function resolveRequestDeptId($requestDeptId): int
|
||||
{
|
||||
if ((int) ($this->adminInfo['id'] ?? 0) === 1) {
|
||||
return AdminScopeHelper::resolveConfigDeptId($this->adminInfo, $requestDeptId);
|
||||
}
|
||||
$deptLogic = new SystemDeptLogic();
|
||||
$deptLogic->init($this->adminInfo);
|
||||
return $deptLogic->resolveAccessibleDeptId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表/下拉按渠道过滤
|
||||
*/
|
||||
protected function applyDeptScope($query, $requestDeptId = null): void
|
||||
{
|
||||
if (!$this->tableHasDeptIdColumn()) {
|
||||
return;
|
||||
}
|
||||
if ((int) ($this->adminInfo['id'] ?? 0) === 1) {
|
||||
$deptId = AdminScopeHelper::resolveConfigDeptId($this->adminInfo, $requestDeptId);
|
||||
$query->where('dept_id', $deptId);
|
||||
return;
|
||||
}
|
||||
$deptLogic = new SystemDeptLogic();
|
||||
$deptLogic->init($this->adminInfo);
|
||||
$deptId = $deptLogic->resolveAccessibleDeptId();
|
||||
if ($deptId > 0) {
|
||||
$query->where('dept_id', $deptId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验角色属于当前可操作渠道
|
||||
*/
|
||||
public function assertRoleWritable($role): void
|
||||
{
|
||||
if (!$this->tableHasDeptIdColumn()) {
|
||||
return;
|
||||
}
|
||||
$roleDeptId = AdminScopeHelper::normalizeRecordDeptId($role->dept_id ?? null);
|
||||
if ((int) ($role->id ?? 0) === SystemRoleChannelService::SUPER_ADMIN_ROLE_ID) {
|
||||
throw new ApiException('Cannot operate super admin role');
|
||||
}
|
||||
if ((int) ($this->adminInfo['id'] ?? 0) === 1) {
|
||||
return;
|
||||
}
|
||||
$deptLogic = new SystemDeptLogic();
|
||||
$deptLogic->init($this->adminInfo);
|
||||
$scopeDeptId = $deptLogic->resolveAccessibleDeptId();
|
||||
if ($scopeDeptId > 0 && $roleDeptId !== $scopeDeptId) {
|
||||
throw new ApiException('No permission to operate this channel role');
|
||||
}
|
||||
}
|
||||
|
||||
protected function assertCodeUniqueInDept(string $code, int $deptId, ?int $excludeId): void
|
||||
{
|
||||
if ($code === '') {
|
||||
return;
|
||||
}
|
||||
$query = SystemRole::where('code', $code)->where('dept_id', $deptId);
|
||||
if ($excludeId !== null && $excludeId > 0) {
|
||||
$query->where('id', '<>', $excludeId);
|
||||
}
|
||||
if ($query->count() > 0) {
|
||||
throw new ApiException('Role code already exists in this channel');
|
||||
}
|
||||
}
|
||||
|
||||
protected function tableHasDeptIdColumn(): bool
|
||||
{
|
||||
try {
|
||||
$fields = Db::getFields((new SystemRole())->getTable());
|
||||
return isset($fields['dept_id']);
|
||||
} catch (\Throwable $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user