MiniProgram.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. <?php
  2. namespace app\common\Service\Third\Wechat;
  3. use app\common\facade\Wechat;
  4. use fast\Random;
  5. use app\common\library\Auth;
  6. use app\common\model\ThirdOauth;
  7. use app\common\exception\BusinessException;
  8. class MiniProgram
  9. {
  10. public $wechat;
  11. protected $request;
  12. protected $payload;
  13. public function __construct($payload = [])
  14. {
  15. $this->payload = $payload;
  16. $this->wechat = Wechat::miniProgram();
  17. }
  18. // 小程序登录
  19. public function login()
  20. {
  21. // https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01
  22. if (empty($this->payload['sessionId'])) {
  23. throw new BusinessException('未获取到登陆态, 请重试');
  24. }
  25. $sessionData = cache($this->payload['sessionId']);
  26. if (empty($sessionData)) {
  27. throw new BusinessException('登陆态已过期, 请重试');
  28. }
  29. $wechatUser = [
  30. 'openid' => $sessionData['openid'],
  31. 'unionid' => $sessionData['unionid'] ?? '',
  32. 'mobile' => '',
  33. 'avatar' => '',
  34. 'nickname' => '',
  35. ];
  36. return $wechatUser;
  37. }
  38. public function bind()
  39. {
  40. if (empty($this->payload['sessionId'])) {
  41. throw new BusinessException('未获取到登陆态, 请重试');
  42. }
  43. $sessionData = cache($this->payload['sessionId']);
  44. if (empty($sessionData)) {
  45. throw new BusinessException('登陆态已过期, 请重试');
  46. }
  47. $wechatUser = [
  48. 'openid' => $sessionData['openid'],
  49. 'unionid' => $sessionData['unionid'] ?? '',
  50. 'avatar' => '',
  51. 'nickname' => '',
  52. ];
  53. return $wechatUser;
  54. }
  55. // 解密微信小程序手机号
  56. public function getUserPhoneNumber()
  57. {
  58. if (empty($this->payload['sessionId'])) {
  59. throw new BusinessException('未获取到登陆态, 请重试');
  60. }
  61. $sessionData = cache($this->payload['sessionId']);
  62. if (empty($sessionData)) {
  63. throw new BusinessException('登陆态已过期, 请重试');
  64. }
  65. $phoneInfo = $this->wechat->encryptor->decryptData($sessionData['session_key'], $this->payload['iv'], $this->payload['encryptedData']);
  66. if (empty($phoneInfo['purePhoneNumber'])) {
  67. throw new BusinessException('获取失败,请重试');
  68. }
  69. if ($phoneInfo['countryCode'] !== '86') {
  70. throw new BusinessException('仅支持大陆地区手机号');
  71. }
  72. return $phoneInfo['purePhoneNumber'];
  73. }
  74. /**
  75. * 获取session_id, 缓存 session_key, openid (unionid), 自动登录
  76. *
  77. * @return string
  78. */
  79. public function getSessionId()
  80. {
  81. if (empty($this->payload['code'])) {
  82. throw new BusinessException('缺少code参数');
  83. }
  84. $decryptData = $this->wechat->auth->session($this->payload['code']);
  85. if(!empty($decryptData['errmsg'])) {
  86. throw new BusinessException($decryptData['errmsg']);
  87. }
  88. if (empty($decryptData['session_key'])) {
  89. throw new BusinessException('未获取到登陆态, 请重试');
  90. }
  91. $auto_login = $this->payload['auto_login'] ?? false;
  92. // 自动登录流程
  93. if($auto_login) {
  94. $oauthInfo = ThirdOauth::getByOpenid($decryptData['openid']);
  95. if($oauthInfo && $oauthInfo->user_id) {
  96. $auth = Auth::instance();
  97. $ret = $auth->direct($oauthInfo->user_id);
  98. if ($ret) {
  99. //set_token_in_header($auth->getToken());
  100. }
  101. }
  102. }
  103. $session_id = Random::uuid();
  104. cache($session_id, $decryptData, 60 * 60 * 24 * 7); // session_key缓存保留一周
  105. return ['session_id' => $session_id, 'auto_login' => $auto_login];
  106. }
  107. }