[权限管理]角色组管理

This commit is contained in:
2026-04-15 10:19:45 +08:00
parent 8cc28096c4
commit 979751f719
7 changed files with 158 additions and 7 deletions

View File

@@ -34,6 +34,7 @@ class Group extends Backend
protected bool $assembleTree = true;
protected array $adminGroups = [];
protected array $manageableGroupIds = [];
protected function initController(Request $request): ?Response
{
@@ -48,6 +49,7 @@ class Group extends Backend
$this->assembleTree = $isTree && !$this->initValue;
$this->adminGroups = Db::name('admin_group_access')->where('uid', $this->auth->id)->column('group_id');
$this->manageableGroupIds = $this->getManageableGroupIds();
return null;
}
@@ -79,6 +81,23 @@ class Group extends Backend
}
$data = $this->excludeFields($data);
$pid = $data['pid'] ?? 0;
$pidInt = intval((string)$pid);
if (!$this->auth->isSuperAdmin() && $pidInt !== 0 && !in_array($pidInt, $this->manageableGroupIds, true)) {
return $this->error(__('You have no permission'));
}
$shouldHandleCommissionRate = true;
if ($shouldHandleCommissionRate) {
if (!$this->isValidCommissionRate($data['commission_rate'] ?? null)) {
return $this->error(__('Please enter the correct field', ['commission_rate']));
}
if ($pidInt !== 0) {
$commissionRes = $this->validateSiblingCommissionRate($pidInt, floatval((string)$data['commission_rate']));
if ($commissionRes !== null) return $commissionRes;
}
} else {
$data['commission_rate'] = 0;
}
$rulesRes = $this->handleRules($data);
if ($rulesRes instanceof Response) return $rulesRes;
@@ -141,6 +160,23 @@ class Group extends Backend
}
$data = $this->excludeFields($data);
$pid = $data['pid'] ?? $row['pid'] ?? 0;
$pidInt = intval((string)$pid);
if (!$this->auth->isSuperAdmin() && $pidInt !== 0 && !in_array($pidInt, $this->manageableGroupIds, true)) {
return $this->error(__('You have no permission'));
}
$shouldHandleCommissionRate = true;
if ($shouldHandleCommissionRate) {
if (!$this->isValidCommissionRate($data['commission_rate'] ?? null)) {
return $this->error(__('Please enter the correct field', ['commission_rate']));
}
if ($pidInt !== 0) {
$commissionRes = $this->validateSiblingCommissionRate($pidInt, floatval((string)$data['commission_rate']), intval((string)$row['id']));
if ($commissionRes !== null) return $commissionRes;
}
} else {
$data['commission_rate'] = 0;
}
$rulesRes = $this->handleRules($data);
if ($rulesRes instanceof Response) return $rulesRes;
@@ -308,11 +344,12 @@ class Group extends Backend
}
if (!$this->auth->isSuperAdmin()) {
$authGroups = $this->auth->getAllAuthGroups($this->authMethod, $where);
if (!$absoluteAuth) {
$authGroups = array_merge($this->adminGroups, $authGroups);
// 仅本人所在角色组 + 其下级子组getManageableGroupIds不包含上级/同级。无父节点在结果集时assembleChild 将该节点作为树根展示,符合「只看我这条线」
$authGroups = $this->manageableGroupIds;
if ($absoluteAuth) {
$authGroups = array_values(array_diff($authGroups, $this->adminGroups));
}
$where[] = ['id', 'in', $authGroups];
$where[] = ['id', 'in', $authGroups ?: [0]];
}
$data = $this->model->where($where)->select()->toArray();
@@ -337,10 +374,48 @@ class Group extends Backend
private function checkAuth($groupId): ?Response
{
$authGroups = $this->auth->getAllAuthGroups($this->authMethod, []);
if (!$this->auth->isSuperAdmin() && !in_array($groupId, $authGroups)) {
$authGroups = $this->manageableGroupIds;
if (!$this->auth->isSuperAdmin() && !in_array(intval((string)$groupId), $authGroups, true)) {
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~'));
}
return null;
}
private function getManageableGroupIds(): array
{
if ($this->auth->isSuperAdmin()) {
return AdminGroup::where('status', 1)->column('id');
}
$own = array_map('intval', $this->adminGroups);
$children = array_map('intval', $this->auth->getAdminChildGroups());
return array_values(array_unique(array_merge($own, $children)));
}
private function isValidCommissionRate(mixed $value): bool
{
if ($value === null || $value === '') {
return false;
}
$rate = trim((string)$value);
if (!preg_match('/^(100(\.00?)?|[0-9]{1,2}(\.[0-9]{1,2})?)$/', $rate)) {
return false;
}
return true;
}
private function validateSiblingCommissionRate(int $pid, float $currentRate, ?int $excludeId = null): ?Response
{
$query = Db::name('admin_group')->where('pid', $pid);
if ($excludeId !== null) {
$query = $query->where('id', '<>', $excludeId);
}
$sum = (float)$query->sum('commission_rate');
$remaining = 100 - $sum;
if ($currentRate > $remaining + 0.000001) {
$exceed = $currentRate - $remaining;
return $this->error(sprintf('同一父级角色组分红比例总和不能超过100%%,当前父级剩余 %.2f%%,本次超出 %.2f%%', max(0, $remaining), $exceed));
}
return null;
}
}