AdminService.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkAdmin
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2014~2021 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: https://gitee.com/zoujingli/ThinkLibrary
  8. // +----------------------------------------------------------------------
  9. // | 开源协议 ( https://mit-license.org )
  10. // +----------------------------------------------------------------------
  11. // | gitee 代码仓库:https://gitee.com/zoujingli/ThinkLibrary
  12. // | github 代码仓库:https://github.com/zoujingli/ThinkLibrary
  13. // +----------------------------------------------------------------------
  14. declare (strict_types=1);
  15. namespace think\admin\service;
  16. use ReflectionException;
  17. use think\admin\extend\DataExtend;
  18. use think\admin\Service;
  19. use think\db\exception\DataNotFoundException;
  20. use think\db\exception\DbException;
  21. use think\db\exception\ModelNotFoundException;
  22. /**
  23. * 系统权限管理服务
  24. * Class AdminService
  25. * @package think\admin\service
  26. */
  27. class AdminService extends Service
  28. {
  29. /**
  30. * 是否已经登录
  31. * @return boolean
  32. */
  33. public function isLogin(): bool
  34. {
  35. return $this->getUserId() > 0;
  36. }
  37. /**
  38. * 是否为超级用户
  39. * @return boolean
  40. */
  41. public function isSuper(): bool
  42. {
  43. return $this->getUserName() === $this->getSuperName();
  44. }
  45. /**
  46. * 获取超级用户账号
  47. * @return string
  48. */
  49. public function getSuperName(): string
  50. {
  51. return $this->app->config->get('app.super_user', 'admin');
  52. }
  53. /**
  54. * 获取后台用户ID
  55. * @return integer
  56. */
  57. public function getUserId(): int
  58. {
  59. return intval($this->app->session->get('user.id', 0));
  60. }
  61. /**
  62. * 获取后台用户名称
  63. * @return string
  64. */
  65. public function getUserName(): string
  66. {
  67. return $this->app->session->get('user.username', '');
  68. }
  69. /**
  70. * 检查指定节点授权
  71. * --- 需要读取缓存或扫描所有节点
  72. * @param null|string $node
  73. * @return boolean
  74. * @throws ReflectionException
  75. */
  76. public function check(?string $node = ''): bool
  77. {
  78. if ($this->isSuper()) return true;
  79. $service = NodeService::instance();
  80. [$real, $nodes] = [$service->fullnode($node), $service->getMethods()];
  81. // 以下代码为兼容 win 控制器不区分大小写的验证问题
  82. foreach ($nodes as $key => $rule) {
  83. if (strpos($key, '_') !== false && strpos($key, '/') !== false) {
  84. $attr = explode('/', $key);
  85. $attr[1] = strtr($attr[1], ['_' => '']);
  86. $nodes[join('/', $attr)] = $rule;
  87. }
  88. }
  89. if (!empty($nodes[$real]['isauth'])) {
  90. return in_array($real, $this->app->session->get('user.nodes', []));
  91. } else {
  92. return !(!empty($nodes[$real]['islogin']) && !$this->isLogin());
  93. }
  94. }
  95. /**
  96. * 获取授权节点列表
  97. * @param array $checkeds
  98. * @return array
  99. * @throws ReflectionException
  100. */
  101. public function getTree(array $checkeds = []): array
  102. {
  103. [$nodes, $pnodes, $methods] = [[], [], array_reverse(NodeService::instance()->getMethods())];
  104. foreach ($methods as $node => $method) {
  105. [$count, $pnode] = [substr_count($node, '/'), substr($node, 0, strripos($node, '/'))];
  106. if ($count === 2 && !empty($method['isauth'])) {
  107. in_array($pnode, $pnodes) or array_push($pnodes, $pnode);
  108. $nodes[$node] = ['node' => $node, 'title' => $method['title'], 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)];
  109. } elseif ($count === 1 && in_array($pnode, $pnodes)) {
  110. $nodes[$node] = ['node' => $node, 'title' => $method['title'], 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)];
  111. }
  112. }
  113. foreach (array_keys($nodes) as $key) foreach ($methods as $node => $method) if (stripos($key, $node . '/') !== false) {
  114. $pnode = substr($node, 0, strripos($node, '/'));
  115. $nodes[$node] = ['node' => $node, 'title' => $method['title'], 'pnode' => $pnode, 'checked' => in_array($node, $checkeds)];
  116. $nodes[$pnode] = ['node' => $pnode, 'title' => ucfirst($pnode), 'pnode' => '', 'checked' => in_array($pnode, $checkeds)];
  117. }
  118. return DataExtend::arr2tree(array_reverse($nodes), 'node', 'pnode', '_sub_');
  119. }
  120. /**
  121. * 初始化用户权限
  122. * @param boolean $force 强刷权限
  123. * @return $this
  124. * @throws DataNotFoundException
  125. * @throws DbException
  126. * @throws ModelNotFoundException
  127. */
  128. public function apply(bool $force = false): AdminService
  129. {
  130. if ($force) $this->clearCache();
  131. if (($uid = $this->app->session->get('user.id'))) {
  132. $user = $this->app->db->name('SystemUser')->where(['id' => $uid])->find();
  133. if (!empty($user['authorize']) && !$this->isSuper()) {
  134. $db = $this->app->db->name('SystemAuth')->field('id')->where(['status' => 1])->whereIn('id', str2arr($user['authorize']));
  135. $user['nodes'] = array_unique($this->app->db->name('SystemAuthNode')->whereRaw("auth in {$db->buildSql()}")->column('node'));
  136. } else {
  137. $user['nodes'] = [];
  138. }
  139. $this->app->session->set('user', $user);
  140. }
  141. return $this;
  142. }
  143. /**
  144. * 清理节点缓存
  145. * @return $this
  146. */
  147. public function clearCache(): AdminService
  148. {
  149. TokenService::instance()->clearCache();
  150. $this->app->cache->delete('SystemAuthNode');
  151. return $this;
  152. }
  153. }