LoginServices.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\services\kefu;
  12. use crmeb\basic\BaseAuth;
  13. use app\services\BaseServices;
  14. use crmeb\exceptions\AuthException;
  15. use crmeb\services\CacheService;
  16. use app\dao\message\service\StoreServiceDao;
  17. use crmeb\services\wechat\OfficialAccount;
  18. use crmeb\utils\ApiErrorCode;
  19. use think\exception\ValidateException;
  20. use app\services\wechat\WechatUserServices;
  21. /**
  22. * 客服登录
  23. * Class LoginServices
  24. * @package app\services\kefu
  25. * @mixin StoreServiceDao
  26. */
  27. class LoginServices extends BaseServices
  28. {
  29. const FEPAORPL = 'OSeCVa';
  30. /**
  31. * LoginServices constructor.
  32. * @param StoreServiceDao $dao
  33. */
  34. public function __construct(StoreServiceDao $dao)
  35. {
  36. $this->dao = $dao;
  37. }
  38. /**
  39. * 客服账号密码登录
  40. * @param string $account
  41. * @param string $password
  42. * @return array
  43. * @throws \think\db\exception\DataNotFoundException
  44. * @throws \think\db\exception\DbException
  45. * @throws \think\db\exception\ModelNotFoundException
  46. */
  47. public function authLogin(string $account, string $password = null)
  48. {
  49. $kefuInfo = $this->dao->get(['account' => $account]);
  50. if (!$kefuInfo) {
  51. throw new ValidateException('没有此用户');
  52. }
  53. if ($password && !password_verify($password, $kefuInfo->password)) {
  54. throw new ValidateException('账号或密码错误');
  55. }
  56. if (!$kefuInfo->status || !$kefuInfo->account_status) {
  57. throw new ValidateException('您已被禁止登录');
  58. }
  59. $token = $this->createToken($kefuInfo->id, 'kefu', $kefuInfo->password);
  60. $kefuInfo->online = 1;
  61. $kefuInfo->update_time = time();
  62. $kefuInfo->ip = request()->ip();
  63. $kefuInfo->save();
  64. return [
  65. 'token' => $token['token'],
  66. 'exp_time' => $token['params']['exp'],
  67. 'kefuInfo' => $kefuInfo->hidden(['password', 'ip', 'update_time', 'add_time', 'status', 'mer_id', 'customer', 'notify'])->toArray()
  68. ];
  69. }
  70. /**
  71. * 解析token
  72. * @param string $token
  73. * @return array
  74. * @throws \Psr\SimpleCache\InvalidArgumentException
  75. * @throws \think\db\exception\DataNotFoundException
  76. * @throws \think\db\exception\DbException
  77. * @throws \think\db\exception\ModelNotFoundException
  78. */
  79. public function parseToken(string $token)
  80. {
  81. /** @var BaseAuth $services */
  82. $services = app()->make(BaseAuth::class);
  83. $adminInfo = $services->parseToken($token, function ($id) {
  84. return $this->dao->get($id);
  85. });
  86. if (isset($adminInfo->auth) && $adminInfo->auth !== md5($adminInfo->password)) {
  87. throw new AuthException(ApiErrorCode::ERR_LOGIN_INVALID);
  88. }
  89. return $adminInfo->hidden(['password', 'ip', 'status']);
  90. }
  91. /**
  92. * @return array
  93. * @throws \think\db\exception\DataNotFoundException
  94. * @throws \think\db\exception\DbException
  95. * @throws \think\db\exception\ModelNotFoundException
  96. */
  97. public function wechatAuth()
  98. {
  99. /** @var OfficialAccount $service */
  100. $service = app()->make(OfficialAccount::class);
  101. $original = $service->setAccessEnd(OfficialAccount::PC)->userFromCode();
  102. if (!$original) {
  103. throw new ValidateException('授权失败');
  104. }
  105. if (!isset($original['unionid'])) {
  106. throw new ValidateException('unionid不存在');
  107. }
  108. /** @var WechatUserServices $userService */
  109. $userService = app()->make(WechatUserServices::class);
  110. $uid = $userService->value(['unionid' => $original['unionid']], 'uid');
  111. if (!$uid) {
  112. throw new ValidateException('获取用户UID失败');
  113. }
  114. $kefuInfo = $this->dao->get(['uid' => $uid]);
  115. if (!$kefuInfo) {
  116. throw new ValidateException('客服不存在');
  117. }
  118. if (!$kefuInfo->status) {
  119. throw new ValidateException('您已被禁止登录');
  120. }
  121. $token = $this->createToken($kefuInfo->id, 'kefu', $kefuInfo->password);
  122. $kefuInfo->update_time = time();
  123. $kefuInfo->ip = request()->ip();
  124. $kefuInfo->save();
  125. return [
  126. 'token' => $token['token'],
  127. 'exp_time' => $token['params']['exp'],
  128. 'kefuInfo' => $kefuInfo->hidden(['password', 'ip', 'update_time', 'add_time', 'status', 'mer_id', 'customer', 'notify'])->toArray()
  129. ];
  130. }
  131. /**
  132. * 检测有没有人扫描登录
  133. * @param string $key
  134. * @return array|int[]
  135. * @throws \Psr\SimpleCache\InvalidArgumentException
  136. * @throws \think\db\exception\DataNotFoundException
  137. * @throws \think\db\exception\DbException
  138. * @throws \think\db\exception\ModelNotFoundException
  139. */
  140. public function scanLogin(string $key)
  141. {
  142. $hasKey = CacheService::has($key);
  143. if ($hasKey === false) {
  144. $status = 0;//不存在需要刷新二维码
  145. } else {
  146. $keyValue = CacheService::get($key);
  147. if ($keyValue === '0') {
  148. $status = 1;//正在扫描中
  149. $kefuInfo = $this->dao->get(['uniqid' => $key], ['account', 'uniqid']);
  150. if ($kefuInfo) {
  151. $tokenInfo = $this->authLogin($kefuInfo->account);
  152. $tokenInfo['status'] = 3;
  153. $kefuInfo->uniqid = '';
  154. $kefuInfo->save();
  155. CacheService::delete($key);
  156. return $tokenInfo;
  157. }
  158. } else {
  159. $status = 2;//没有扫描
  160. }
  161. }
  162. return ['status' => $status];
  163. }
  164. }