'admin_group', 'auth_group_access' => 'admin_group_access', 'auth_rule' => 'admin_rule', ]; protected array $children = []; public function __construct(array $config = []) { $this->config = array_merge($this->config, $config); } public function __get($name): mixed { return $this->config[$name] ?? null; } public function getMenus(int $uid): array { $this->children = []; $originAuthRules = $this->getOriginAuthRules($uid); foreach ($originAuthRules as $rule) { $this->children[$rule['pid']][] = $rule; } if (!isset($this->children[0])) { return []; } return $this->getChildren($this->children[0]); } private function getChildren(array $rules): array { foreach ($rules as $key => $rule) { if (array_key_exists($rule['id'], $this->children)) { $rules[$key]['children'] = $this->getChildren($this->children[$rule['id']]); } } return $rules; } public function check(string $name, int $uid, string $relation = 'or', string $mode = 'url'): bool { $ruleList = $this->getRuleList($uid); if (in_array('*', $ruleList)) { return true; } if ($name) { $name = strtolower($name); $name = str_contains($name, ',') ? explode(',', $name) : [$name]; } $list = []; $requestParams = []; if ($mode === 'url' && function_exists('request')) { $req = request(); $requestParams = $req ? array_merge($req->get(), $req->post()) : []; $requestParams = json_decode(strtolower(json_encode($requestParams, JSON_UNESCAPED_UNICODE)), true) ?? []; } foreach ($ruleList as $rule) { $query = preg_replace('/^.+\?/U', '', $rule); if ($mode === 'url' && $query !== $rule) { parse_str($query, $param); $intersect = array_intersect_assoc($requestParams, $param); $rule = preg_replace('/\?.*$/U', '', $rule); if (in_array($rule, $name) && $intersect == $param) { $list[] = $rule; } } elseif (in_array($rule, $name)) { $list[] = $rule; } } if ($relation === 'or' && !empty($list)) { return true; } $diff = array_diff($name, $list); if ($relation === 'and' && empty($diff)) { return true; } return false; } public function getRuleList(int $uid): array { $ids = $this->getRuleIds($uid); if (empty($ids)) { return []; } $originAuthRules = $this->getOriginAuthRules($uid); $rules = []; if (in_array('*', $ids)) { $rules[] = '*'; } foreach ($originAuthRules as $rule) { $rules[$rule['id']] = strtolower($rule['name']); } return array_unique($rules); } public function getOriginAuthRules(int $uid): array { $ids = $this->getRuleIds($uid); if (empty($ids)) { return []; } $where = [['status', '=', '1']]; if (!in_array('*', $ids)) { $where[] = ['id', 'in', $ids]; } $rules = Db::name($this->config['auth_rule']) ->withoutField(['remark', 'status', 'weigh', 'update_time', 'create_time']) ->where($where) ->order('weigh desc,id asc') ->select() ->toArray(); foreach ($rules as $key => $rule) { if (!empty($rule['keepalive'])) { $rules[$key]['keepalive'] = $rule['name']; } } return $rules; } public function getRuleIds(int $uid): array { $groups = $this->getGroups($uid); $ids = []; foreach ($groups as $g) { $ids = array_merge($ids, explode(',', trim($g['rules'] ?? '', ','))); } return array_unique($ids); } public function getGroups(int $uid): array { $dbName = $this->config['auth_group_access'] ?: 'user'; if ($this->config['auth_group_access']) { $userGroups = Db::name($dbName) ->alias('aga') ->join($this->config['auth_group'] . ' ag', 'aga.group_id = ag.id', 'LEFT') ->field('aga.uid,aga.group_id,ag.id,ag.pid,ag.name,ag.rules') ->where("aga.uid='$uid' and ag.status='1'") ->select() ->toArray(); } else { $userGroups = Db::name($dbName) ->alias('u') ->join($this->config['auth_group'] . ' ag', 'u.group_id = ag.id', 'LEFT') ->field('u.id as uid,u.group_id,ag.id,ag.name,ag.rules') ->where("u.id='$uid' and ag.status='1'") ->select() ->toArray(); } return $userGroups; } }