MiniProgram.php 3.7 KB

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