UserService.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. namespace App\Services;
  3. use App\Owner;
  4. use App\User;
  5. use App\UserWorkgroup;
  6. use Firebase\JWT\JWT;
  7. use Illuminate\Database\Eloquent\Model;
  8. use Illuminate\Support\Facades\Auth;
  9. use Illuminate\Support\Facades\Cache;
  10. use App\Traits\ServiceAppAop;
  11. use Illuminate\Support\Facades\Log;
  12. class UserService
  13. {
  14. use ServiceAppAop;
  15. protected $modelClass=User::class;
  16. /** @var CacheService $cacheService */
  17. private $cacheService;
  18. function __construct(){
  19. $this->cacheService = app('CacheService');
  20. }
  21. function hasRoles(User $user, $roles){
  22. $thisRoles=$this->cacheService->getOrExecute("user{$user['id']}->roles",function()use($user){
  23. return $user->roles;
  24. });
  25. return !!$roles->intersect($thisRoles)->count();
  26. }
  27. function getPermittingOwnerIds($user=null){
  28. if(!$user)return [];
  29. return $this->cacheService->getOrExecute("user{$user['id']}->getPermittingOwnerIds",function()use($user){
  30. return $user->getPermittingOwnerIdsAttribute() ?? [];
  31. })??[];
  32. }
  33. function getPermittingLogisticIds($user=null){
  34. if(!$user)return [];
  35. return $this->cacheService->getOrExecute("user{$user['id']}->getPermittingLogisticIds",function()use($user){
  36. return $user->getPermittingLogisticIdsAttribute() ?? [];
  37. })??[];
  38. }
  39. /**
  40. * 检查用户的管理员身份
  41. *
  42. * @param integer $userId
  43. *
  44. * @return bool
  45. */
  46. public function checkAdminIdentity(int $userId):bool
  47. {
  48. if ($userId == Auth::id())return array_search(Auth::user()["name"],config("users.superAdmin"))!==false;
  49. /** @var User|\stdClass $user */
  50. $user = User::query()->select("name")->find($userId);
  51. if (!$user)return false;
  52. return array_search($user->name,config("users.superAdmin"))!==false;
  53. }
  54. /**
  55. * @param integer|null $userId
  56. *
  57. * @return array
  58. */
  59. public function getUserHasOwners($userId = null)
  60. {
  61. if (!$userId)$userId = Auth::id();
  62. $key = "owners:user_".$userId;
  63. if (!Cache::has($key)){
  64. if ($this->checkAdminIdentity($userId))Cache::forever($key,array_column(Owner::query()->select("id")->whereNull("deleted_at")->get()->toArray(),"id"));
  65. else{
  66. $owners = [];
  67. /** @var User|\stdClass $user */
  68. $user = new User();
  69. $user->id = $userId;
  70. $user->load("roles.owners");
  71. $user->roles->each(function ($role)use (&$owners){
  72. $owners = array_merge($owners,array_column($role->owners->toArray(),"id"));
  73. });
  74. Cache::forever($key,$owners);
  75. }
  76. }
  77. return Cache::get($key);
  78. }
  79. /**
  80. * @param integer|null $userId
  81. *
  82. * @return array
  83. */
  84. public function getUserHasUserWorkGroups($userId = null)
  85. {
  86. if (!$userId)$userId = Auth::id();
  87. $key = "userWorkGroups:user_".$userId;
  88. if (!Cache::has($key)){
  89. if ($this->checkAdminIdentity($userId))Cache::forever($key,array_column(UserWorkgroup::query()->select("id")->get()->toArray(),"id"));
  90. else{
  91. $userWorkGroups = [];
  92. /** @var User|\stdClass $user */
  93. $user = new User();
  94. $user->id = $userId;
  95. $user->load("roles.userWorkGroups");
  96. $user->roles->each(function ($role)use (&$userWorkGroups){
  97. $userWorkGroups = array_merge($userWorkGroups,array_column($role->userWorkGroups->toArray(),"id"));
  98. });
  99. Cache::forever($key,$userWorkGroups);
  100. }
  101. }
  102. return Cache::get($key);
  103. }
  104. /**
  105. * 清除用户缓存
  106. *
  107. * @param User $user
  108. */
  109. public function clearUserCache(User $user)
  110. {
  111. Cache::tags("authorities:user")->forget("authorities:user_".$user->id);
  112. Cache::tags("authorities:user")->forget("authorities:android:user_".$user->id);
  113. Cache::forget("owners:user_".$user->id);
  114. Cache::forget("userWorkGroups:user_".$user->id);
  115. Cache::tags("AUTHORITY_MENU_MAPPING")->forget("am_mapping_".$user->id);
  116. Cache::tags("USERS")->pull("user_info_".$user->id);
  117. }
  118. /**
  119. * 获取JWT token
  120. *
  121. * @param User|\stdClass $user
  122. * @param mixed $key
  123. * @return string
  124. */
  125. public function getJWTToken($user,$key):string
  126. {
  127. $time = time();
  128. $payload = [
  129. 'iss' => $_SERVER["HTTP_HOST"], //签发者
  130. 'iat' => $time,
  131. 'nbf' => $time,
  132. 'exp' => $time+config("api.timeliness_limits.token","7200"),
  133. 'data' => [
  134. 'id' => $user->id,
  135. 'username' => $user->name
  136. ]
  137. ];
  138. $alg = 'RS256';
  139. return JWT::encode($payload, $key, $alg);
  140. }
  141. /**
  142. * 设置或刷新缓存
  143. *
  144. * @param User|\stdClass|Model $user
  145. * @param null $exp
  146. */
  147. public function setOrRefreshCache($user, $exp = null)
  148. {
  149. if (!$exp)$exp = config("api.timeliness_limits.token","7200");
  150. Cache::tags("USERS")->put("user_info_".$user->id,$user,$exp);
  151. }
  152. /**
  153. * @param integer $id
  154. * @param integer $exp
  155. * @return User|\stdClass|null
  156. */
  157. public function getOrRefreshCache(int $id,int $exp):?Model
  158. {
  159. $user = Cache::tags("USERS")->get("user_info_".$id);
  160. if ($user)return $user;
  161. $user = User::query()->find($id);
  162. if (!$user)return null;
  163. $time = $exp-time();
  164. $this->setOrRefreshCache($user,$time>0 ? $time : 7200);
  165. return $user;
  166. }
  167. public function setSingleTag($key, $token)
  168. {
  169. $val = $token."#".md5($_SERVER['HTTP_USER_AGENT']);
  170. Cache::tags(User::ANDROID_SINGLE_TAG)->put($key,$val,
  171. config("api.timeliness_limits.token","7200"));
  172. }
  173. public function verifySingleTag($key, $token):bool
  174. {
  175. $tV = Cache::tags(User::ANDROID_SINGLE_TAG)->get($key);
  176. if ($tV===null)return true;
  177. $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? "#".md5($_SERVER['HTTP_USER_AGENT']) : "";
  178. return $tV===($token.$userAgent);
  179. }
  180. }