优化管理员日志管理只显示当前组以及以下的数据

This commit is contained in:
2026-04-02 11:35:08 +08:00
parent e93c58c7df
commit 81dc7de560
8 changed files with 107 additions and 20 deletions

View File

@@ -21,7 +21,10 @@ class Admin extends Backend
protected array|string $quickSearchField = ['username', 'nickname']; protected array|string $quickSearchField = ['username', 'nickname'];
protected string|int|bool $dataLimit = 'allAuthAndOthers'; /**
* 开启数据范围;具体范围见重写的 getDataLimitAdminIds角色组树仅本人 + 下级组内管理员)
*/
protected bool|string|int $dataLimit = true;
protected string $dataLimitField = 'id'; protected string $dataLimitField = 'id';
@@ -31,6 +34,17 @@ class Admin extends Backend
return null; return null;
} }
/**
* 非超管:仅可管理「本人 + 树形下级组内」的管理员账号;与角色组管理页的可见范围一致(列表不含仅同级的其他管理员)
*/
protected function getDataLimitAdminIds(): array
{
if (!$this->dataLimit || !$this->auth || $this->auth->isSuperAdmin()) {
return [];
}
return $this->auth->getSelfAndSubordinateAdminIds();
}
public function index(Request $request): Response public function index(Request $request): Response
{ {
$response = $this->initializeBackend($request); $response = $this->initializeBackend($request);
@@ -357,9 +371,12 @@ class Admin extends Backend
if ($this->auth->isSuperAdmin()) { if ($this->auth->isSuperAdmin()) {
return null; return null;
} }
$authGroups = $this->auth->getAllAuthGroups('allAuthAndOthers'); $allowedGroupIds = array_values(array_unique(array_merge(
Db::name('admin_group_access')->where('uid', $this->auth->id)->column('group_id'),
$this->auth->getAdminChildGroups()
)));
foreach ($groups as $group) { foreach ($groups as $group) {
if (!in_array($group, $authGroups)) { if (!in_array($group, $allowedGroupIds, false)) {
return $this->error(__('You have no permission to add an administrator to this group!')); return $this->error(__('You have no permission to add an administrator to this group!'));
} }
} }

View File

@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace app\admin\controller\auth; namespace app\admin\controller\auth;
use Throwable;
use app\common\controller\Backend; use app\common\controller\Backend;
use app\admin\model\AdminLog as AdminLogModel; use app\admin\model\AdminLog as AdminLogModel;
use support\Response; use support\Response;
@@ -36,7 +35,10 @@ class AdminLog extends Backend
list($where, $alias, $limit, $order) = $this->queryBuilder(); list($where, $alias, $limit, $order) = $this->queryBuilder();
if (!$this->auth->isSuperAdmin()) { if (!$this->auth->isSuperAdmin()) {
$where[] = ['admin_id', '=', $this->auth->id]; $scopeIds = $this->auth->getSelfAndSubordinateAdminIds();
if ($scopeIds !== []) {
$where[] = ['admin_id', 'in', $scopeIds];
}
} }
$res = $this->model $res = $this->model
->withJoin($this->withJoinTable, $this->withJoinType) ->withJoin($this->withJoinTable, $this->withJoinType)

View File

@@ -17,8 +17,6 @@ use Webman\Http\Request;
class Group extends Backend class Group extends Backend
{ {
protected string $authMethod = 'allAuthAndOthers';
protected ?object $model = null; protected ?object $model = null;
protected string|array $preExcludeFields = ['create_time', 'update_time']; protected string|array $preExcludeFields = ['create_time', 'update_time'];
@@ -82,6 +80,9 @@ class Group extends Backend
$rulesRes = $this->handleRules($data); $rulesRes = $this->handleRules($data);
if ($rulesRes instanceof Response) return $rulesRes; if ($rulesRes instanceof Response) return $rulesRes;
$pidRes = $this->validateGroupParentId($data['pid'] ?? null);
if ($pidRes instanceof Response) return $pidRes;
$result = false; $result = false;
$this->model->startTrans(); $this->model->startTrans();
try { try {
@@ -144,6 +145,11 @@ class Group extends Backend
$rulesRes = $this->handleRules($data); $rulesRes = $this->handleRules($data);
if ($rulesRes instanceof Response) return $rulesRes; if ($rulesRes instanceof Response) return $rulesRes;
if (array_key_exists('pid', $data)) {
$pidRes = $this->validateGroupParentId($data['pid'] ?? null);
if ($pidRes instanceof Response) return $pidRes;
}
$result = false; $result = false;
$this->model->startTrans(); $this->model->startTrans();
try { try {
@@ -294,8 +300,6 @@ class Group extends Backend
$pk = $this->model->getPk(); $pk = $this->model->getPk();
$initKey = $request->get('initKey') ?? $pk; $initKey = $request->get('initKey') ?? $pk;
$absoluteAuth = $request->get('absoluteAuth') ?? false;
if ($this->keyword) { if ($this->keyword) {
$keyword = explode(' ', $this->keyword); $keyword = explode(' ', $this->keyword);
foreach ($keyword as $item) { foreach ($keyword as $item) {
@@ -308,11 +312,14 @@ class Group extends Backend
} }
if (!$this->auth->isSuperAdmin()) { if (!$this->auth->isSuperAdmin()) {
$authGroups = $this->auth->getAllAuthGroups($this->authMethod, $where); $descendantIds = $this->auth->getAdminChildGroups();
if (!$absoluteAuth) { // 本人所在组 + 树形下级;不含同级、不含其它分支(与 getAllAuthGroups 的「权限多寡」脱钩)
$authGroups = array_merge($this->adminGroups, $authGroups); $visibleIds = array_values(array_unique(array_merge($this->adminGroups, $descendantIds)));
if ($visibleIds === []) {
$where[] = ['id', '=', -1];
} else {
$where[] = ['id', 'in', $visibleIds];
} }
$where[] = ['id', 'in', $authGroups];
} }
$data = $this->model->where($where)->select()->toArray(); $data = $this->model->where($where)->select()->toArray();
@@ -337,9 +344,43 @@ class Group extends Backend
private function checkAuth($groupId): ?Response private function checkAuth($groupId): ?Response
{ {
$authGroups = $this->auth->getAllAuthGroups($this->authMethod, []); if ($this->auth->isSuperAdmin()) {
if (!$this->auth->isSuperAdmin() && !in_array($groupId, $authGroups)) { return null;
return $this->error(__($this->authMethod == 'allAuth' ? 'You need to have all permissions of this group to operate this group~' : 'You need to have all the permissions of the group and have additional permissions before you can operate the group~')); }
$descendantIds = $this->auth->getAdminChildGroups();
if (!in_array($groupId, $descendantIds, false)) {
return $this->error(__('You can only operate subordinate role groups in the tree hierarchy~'));
}
return null;
}
/**
* 新增/编辑时校验父级:非超管只能挂在本人所在组或其树形下级之下,不可建顶级(pid=0)
*/
private function validateGroupParentId(mixed $pid): ?Response
{
if ($this->auth->isSuperAdmin()) {
return null;
}
if ($pid === null || $pid === '' || $pid === false) {
return $this->error(__('Non super administrators cannot create top-level role groups'));
}
if ($pid === 0 || $pid === '0') {
return $this->error(__('Non super administrators cannot create top-level role groups'));
}
if (!is_numeric($pid)) {
return $this->error(__('The parent group is not within your manageable scope'));
}
$allowed = array_values(array_unique(array_merge($this->adminGroups, $this->auth->getAdminChildGroups())));
$ok = false;
foreach ($allowed as $aid) {
if ($aid == $pid) {
$ok = true;
break;
}
}
if (!$ok) {
return $this->error(__('The parent group is not within your manageable scope'));
} }
return null; return null;
} }

View File

@@ -9,5 +9,8 @@ return [
'You need to have all the permissions of the group and have additional permissions before you can operate the group~' => 'You need to have all the permissions of the group and have additional permissions before you can operate the group~', 'You need to have all the permissions of the group and have additional permissions before you can operate the group~' => 'You need to have all the permissions of the group and have additional permissions before you can operate the group~',
'Role group has all your rights, please contact the upper administrator to add or do not need to add!' => 'Role group has all your rights, please contact the upper administrator to add or do not need to add!', 'Role group has all your rights, please contact the upper administrator to add or do not need to add!' => 'Role group has all your rights, please contact the upper administrator to add or do not need to add!',
'The group permission node exceeds the range that can be allocated' => 'The group permission node exceeds the range that can be allocated, please refresh and try again~', 'The group permission node exceeds the range that can be allocated' => 'The group permission node exceeds the range that can be allocated, please refresh and try again~',
'Remark lang' => 'For system security, the hierarchical relationship of role groups is for reference only. The actual hierarchy is determined by the number of permission nodes: same permissions = peer, containing and having additional permissions = superior. Peers cannot manage peers; superiors can assign their permission nodes to subordinates. For special cases where an admin needs to become a superior, create a virtual permission node.', 'You can only operate subordinate role groups in the tree hierarchy~' => 'You can only manage role groups that are strictly below yours in the role-group tree (not peers or other branches).',
'Non super administrators cannot create top-level role groups' => 'Non super administrators cannot create top-level role groups',
'The parent group is not within your manageable scope' => 'The selected parent group is outside your manageable scope',
'Remark lang' => 'Role groups follow the tree (parent/child): you may only manage groups under your own membership branch; peers, other branches and ancestors cannot be managed here. When assigning rules you can still only select permission nodes you own.',
]; ];

View File

@@ -9,5 +9,8 @@ return [
'You need to have all the permissions of the group and have additional permissions before you can operate the group~' => '您需要拥有该分组的所有权限且还有额外权限时,才可以操作该分组~', 'You need to have all the permissions of the group and have additional permissions before you can operate the group~' => '您需要拥有该分组的所有权限且还有额外权限时,才可以操作该分组~',
'Role group has all your rights, please contact the upper administrator to add or do not need to add!' => '角色组拥有您的全部权限,请联系上级管理员添加或无需添加!', 'Role group has all your rights, please contact the upper administrator to add or do not need to add!' => '角色组拥有您的全部权限,请联系上级管理员添加或无需添加!',
'The group permission node exceeds the range that can be allocated' => '分组权限节点超出可分配范围,请刷新重试~', 'The group permission node exceeds the range that can be allocated' => '分组权限节点超出可分配范围,请刷新重试~',
'Remark lang' => '为保障系统安全,角色组本身的上下级关系仅供参考,系统的实际上下级划分是根据`权限多寡`来确定的,两位管理员的权限节点:相同被认为是`同级`、包含且有额外权限才被认为是`上级`,同级不可管理同级,上级可为下级分配自己拥有的权限节点;若有特殊情况管理员需转`上级`,可建立一个虚拟权限节点', 'You can only operate subordinate role groups in the tree hierarchy~' => '仅可管理在角色组树中属于您下级的角色组(不含同级、不含其他分支)~',
'Non super administrators cannot create top-level role groups' => '非超级管理员不能创建顶级角色组',
'The parent group is not within your manageable scope' => '所选父级角色组不在您可管理的范围内',
'Remark lang' => '角色组以「树形父子关系」为准:仅可管理本人所在组之下的下级组;同级、其他分支及上级组不可在此管理。分配权限时仍只能勾选您自身拥有的权限节点。',
]; ];

View File

@@ -297,6 +297,26 @@ class Auth extends \ba\Auth
return array_unique($children); return array_unique($children);
} }
/**
* 本人 + 树形下级角色组内的管理员 ID与管理员管理列表数据范围一致
*/
public function getSelfAndSubordinateAdminIds(): array
{
if ($this->isSuperAdmin()) {
return [];
}
$descendantGroupIds = $this->getAdminChildGroups();
$adminIds = [];
if ($descendantGroupIds !== []) {
$adminIds = Db::name('admin_group_access')
->where('group_id', 'in', $descendantGroupIds)
->column('uid');
}
$adminIds[] = $this->id;
return array_values(array_unique($adminIds));
}
public function getGroupChildGroups(int $groupId, array &$children): void public function getGroupChildGroups(int $groupId, array &$children): void
{ {
$childrenTemp = AdminGroup::where('pid', $groupId) $childrenTemp = AdminGroup::where('pid', $groupId)

View File

@@ -5,5 +5,5 @@ export default {
'Parent group': 'Superior group', 'Parent group': 'Superior group',
'The parent group cannot be the group itself': 'The parent group cannot be the group itself', 'The parent group cannot be the group itself': 'The parent group cannot be the group itself',
'Manage subordinate role groups here': 'Manage subordinate role groups here':
'In managing a subordinate role group (excluding a peer role group), you have all the rights of a subordinate role group and additional rights', 'You can only manage role groups under your branch in the tree; peers, other branches and ancestors are out of scope. You can still only assign permission nodes you own.',
} }

View File

@@ -4,5 +4,6 @@ export default {
jurisdiction: '权限', jurisdiction: '权限',
'Parent group': '上级分组', 'Parent group': '上级分组',
'The parent group cannot be the group itself': '上级分组不能是分组本身', 'The parent group cannot be the group itself': '上级分组不能是分组本身',
'Manage subordinate role groups here': '在此管理下级角色组(您拥有下级角色组的所有权限并且拥有额外的权限,不含同级)', 'Manage subordinate role groups here':
'在此仅可管理「角色组树」中您所在组之下的下级组;同级、其他分支与上级组不在管理范围内。分配权限时仍只能勾选您自身拥有的节点。',
} }