User.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. <?php
  2. namespace app\api\model;
  3. use think\Cache;
  4. use app\api\model\dealer\Referee as RefereeModel;
  5. use app\api\model\dealer\Setting as DealerSettingModel;
  6. use app\common\model\User as UserModel;
  7. use app\common\library\helper;
  8. use app\common\library\wechat\WxUser;
  9. use app\common\exception\BaseException;
  10. /**
  11. * 用户模型类
  12. * Class User
  13. * @package app\api\model
  14. */
  15. class User extends UserModel
  16. {
  17. private $token;
  18. /**
  19. * 隐藏字段
  20. * @var array
  21. */
  22. protected $hidden = [
  23. 'open_id',
  24. 'is_delete',
  25. 'wxapp_id',
  26. 'create_time',
  27. 'update_time'
  28. ];
  29. /**
  30. * 获取用户信息
  31. * @param $token
  32. * @return null|static
  33. * @throws \think\exception\DbException
  34. */
  35. public static function getUser($token)
  36. {
  37. $openId = Cache::get($token)['openid'];
  38. return self::detail(['open_id' => $openId], ['address', 'addressDefault', 'grade']);
  39. }
  40. /**
  41. * 用户登录
  42. * @param array $post
  43. * @return string
  44. * @throws BaseException
  45. * @throws \think\Exception
  46. * @throws \think\exception\DbException
  47. */
  48. public function login($post)
  49. {
  50. // 微信登录 获取session_key
  51. $session = $this->wxlogin($post['code']);
  52. // 自动注册用户
  53. $refereeId = isset($post['referee_id']) ? $post['referee_id'] : null;
  54. $userInfo = helper::jsonDecode(htmlspecialchars_decode($post['user_info']));
  55. $user_id = $this->register($session['openid'], $userInfo, $refereeId);
  56. // 生成token (session3rd)
  57. $this->token = $this->token($session['openid']);
  58. // 记录缓存, 7天
  59. Cache::set($this->token, $session, 86400 * 7);
  60. return $user_id;
  61. }
  62. /**
  63. * 获取token
  64. * @return mixed
  65. */
  66. public function getToken()
  67. {
  68. return $this->token;
  69. }
  70. /**
  71. * 微信登录
  72. * @param $code
  73. * @return array|mixed
  74. * @throws BaseException
  75. * @throws \think\exception\DbException
  76. */
  77. private function wxlogin($code)
  78. {
  79. // 获取当前小程序信息
  80. $wxConfig = Wxapp::getWxappCache();
  81. // 验证appid和appsecret是否填写
  82. if (empty($wxConfig['app_id']) || empty($wxConfig['app_secret'])) {
  83. throw new BaseException(['msg' => '请到 [后台-小程序设置] 填写appid 和 appsecret']);
  84. }
  85. // 微信登录 (获取session_key)
  86. $WxUser = new WxUser($wxConfig['app_id'], $wxConfig['app_secret']);
  87. if (!$session = $WxUser->sessionKey($code)) {
  88. throw new BaseException(['msg' => $WxUser->getError()]);
  89. }
  90. return $session;
  91. }
  92. /**
  93. * 生成用户认证的token
  94. * @param $openid
  95. * @return string
  96. */
  97. private function token($openid)
  98. {
  99. $wxapp_id = self::$wxapp_id;
  100. // 生成一个不会重复的随机字符串
  101. $guid = \getGuidV4();
  102. // 当前时间戳 (精确到毫秒)
  103. $timeStamp = microtime(true);
  104. // 自定义一个盐
  105. $salt = 'token_salt';
  106. return md5("{$wxapp_id}_{$timeStamp}_{$openid}_{$guid}_{$salt}");
  107. }
  108. /**
  109. * 自动注册用户
  110. * @param $open_id
  111. * @param $data
  112. * @param int $refereeId
  113. * @return mixed
  114. * @throws \Exception
  115. * @throws \think\exception\DbException
  116. */
  117. private function register($open_id, $data, $refereeId = null)
  118. {
  119. // 查询用户是否已存在
  120. $user = self::detail(['open_id' => $open_id]);
  121. $model = $user ?: $this;
  122. $this->startTrans();
  123. try {
  124. // 保存/更新用户记录
  125. if (!$model->allowField(true)->save(array_merge($data, [
  126. 'open_id' => $open_id,
  127. 'wxapp_id' => self::$wxapp_id
  128. ]))) {
  129. throw new BaseException(['msg' => '用户注册失败']);
  130. }
  131. // 记录推荐人关系
  132. if (!$user && $refereeId > 0) {
  133. RefereeModel::createRelation($model['user_id'], $refereeId);
  134. }
  135. $this->commit();
  136. } catch (\Exception $e) {
  137. $this->rollback();
  138. throw new BaseException(['msg' => $e->getMessage()]);
  139. }
  140. return $model['user_id'];
  141. }
  142. /**
  143. * 个人中心菜单列表
  144. * @return array
  145. */
  146. public function getMenus()
  147. {
  148. $menus = [
  149. 'address' => [
  150. 'name' => '收货地址',
  151. 'url' => 'pages/address/index',
  152. 'icon' => 'map'
  153. ],
  154. 'coupon' => [
  155. 'name' => '领券中心',
  156. 'url' => 'pages/coupon/coupon',
  157. 'icon' => 'lingquan'
  158. ],
  159. 'my_coupon' => [
  160. 'name' => '我的优惠券',
  161. 'url' => 'pages/user/coupon/coupon',
  162. 'icon' => 'youhuiquan'
  163. ],
  164. 'sharing_order' => [
  165. 'name' => '拼团订单',
  166. 'url' => 'pages/sharing/order/index',
  167. 'icon' => 'pintuan'
  168. ],
  169. 'my_bargain' => [
  170. 'name' => '我的砍价',
  171. 'url' => 'pages/bargain/index/index?tab=1',
  172. 'icon' => 'kanjia'
  173. ],
  174. 'dealer' => [
  175. 'name' => '分销中心',
  176. 'url' => 'pages/dealer/index/index',
  177. 'icon' => 'fenxiaozhongxin'
  178. ],
  179. 'help' => [
  180. 'name' => '我的帮助',
  181. 'url' => 'pages/user/help/index',
  182. 'icon' => 'help'
  183. ],
  184. ];
  185. // 判断分销功能是否开启
  186. if (DealerSettingModel::isOpen()) {
  187. $menus['dealer']['name'] = DealerSettingModel::getDealerTitle();
  188. } else {
  189. unset($menus['dealer']);
  190. }
  191. return $menus;
  192. }
  193. }