[权限管理]角色组管理
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -94,5 +94,6 @@ return [
|
||||
'No rows were restore' => 'No rows were restored',
|
||||
'%d records and files have been deleted' => '%d records and files have been deleted',
|
||||
'Please input correct username' => 'Please enter the correct username',
|
||||
'Please enter a valid commission rate for non-top role group' => 'Non-top role groups require a commission rate between 0 and 100 (%)',
|
||||
'Group Name Arr' => 'Group Name Arr',
|
||||
];
|
||||
@@ -113,5 +113,6 @@ return [
|
||||
'No rows were restore' => '未恢复任何行',
|
||||
'%d records and files have been deleted' => '已删除%d条记录和文件',
|
||||
'Please input correct username' => '请输入正确的用户名',
|
||||
'Please enter a valid commission rate for non-top role group' => '非顶级角色组须填写 0~100 的分红比例(%)',
|
||||
'Group Name Arr' => '分组名称数组',
|
||||
];
|
||||
Reference in New Issue
Block a user