User.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?php
  2. namespace addons\exam\controller;
  3. use addons\exam\library\CacheService;
  4. use addons\exam\library\WechatService;
  5. use addons\exam\model\UserInfoModel;
  6. use addons\exam\model\UserModel;
  7. use app\common\library\Token;
  8. use think\Validate;
  9. /**
  10. * 会员接口
  11. */
  12. class User extends Base
  13. {
  14. protected $noNeedLogin = ['login', 'userLogin', 'register'];
  15. protected $noNeedRight = '*';
  16. protected $visibleFields = ['id', 'avatar', 'gender', 'nickname', 'mobile', 'birthday', 'status', 'createtime', 'logintime'];
  17. /**
  18. * 授权登录
  19. * @ApiMethod (POST)
  20. * @param string $code 授权code
  21. * @param string $userInfo 授权后拿到的用户信息
  22. */
  23. public function login()
  24. {
  25. $user_info = input('userInfo/a', []);
  26. $code = input('code/s', '');
  27. $from_user_id = input('from_user_id/d', 0);
  28. if (!$code) {
  29. fail('缺少小程序参数code');
  30. }
  31. if (!$user_info) {
  32. fail('缺少小程序参数userInfo');
  33. }
  34. $service = new WechatService();
  35. $wechat_user = $service->miniLogin($code);
  36. if (!isset($wechat_user['openid'])) {
  37. fail('获取小程序用户信息失败');
  38. }
  39. $open_id = $wechat_user['openid'];
  40. $session_key = $wechat_user['session_key'] ?? '';
  41. $user = UserModel::get(['username' => $open_id]);
  42. if (empty($user)) {
  43. $user = UserModel::fastRegister($open_id, $user_info['nickName'] ?? '', $user_info['avatarUrl'] ?? '', $user_info['gender'] ?? 0);
  44. if (!$user) {
  45. fail('注册用户失败');
  46. }
  47. } else {
  48. $data = [
  49. // 'nickname' => $user_info['nickName'],
  50. // 'avatar' => $user_info['avatarUrl'],
  51. 'logintime' => time(),
  52. ];
  53. // if (!$user->parent_id) {
  54. // $data['parent_id'] = $from_user_id;
  55. // }
  56. $user->isUpdate(true)->save($data);
  57. }
  58. // 记录session_key,用于后续获取手机号码等功能
  59. CacheService::setWechatUserSessionKey($user->id, $session_key);
  60. // 清除之前的token
  61. Token::clear($user->id);
  62. // 直接登录
  63. $this->auth->direct($user->id);
  64. // 用户扩展信息
  65. $info = UserInfoModel::getUserInfo($user->id);
  66. $this->success('', [
  67. 'token' => $this->auth->getToken(),
  68. 'user' => array_merge($user->only($this->visibleFields), ['info' => $info->toArray()]),
  69. ]);
  70. }
  71. /**
  72. * 用户信息
  73. */
  74. public function info()
  75. {
  76. $user = $this->auth->getUser()->visible($this->visibleFields)->toArray();
  77. $user['info'] = UserInfoModel::getUserInfo($this->auth->id);
  78. if ($user && $user['avatar']) {
  79. if (strpos($user['avatar'], 'http') === false) {
  80. $user['avatar'] = cdnurl($user['avatar'], true);
  81. }
  82. }
  83. $this->success('', $user);
  84. }
  85. /**
  86. * 获取微信绑定的手机号码
  87. */
  88. public function getWechatPhone()
  89. {
  90. $iv = input('iv/s', '');
  91. $encryptedData = input('encryptedData/s', '');
  92. if (!$iv) {
  93. fail('缺少小程序参数iv');
  94. }
  95. if (!$encryptedData) {
  96. fail('缺少小程序参数encryptedData');
  97. }
  98. if (!$session_key = CacheService::getWechatUserSessionKey($this->auth->id)) {
  99. fail('微信sessionKey丢失,请重新登录再试');
  100. }
  101. // try {
  102. $service = new WechatService();
  103. $data = $service->decryptedData($session_key, $iv, $encryptedData);
  104. succ($data);
  105. // } catch (\Exception $exception) {
  106. // fail('sessionKey失效,请重新登录再试:' . $exception->getMessage());
  107. // }
  108. }
  109. /**
  110. * 保存个人信息
  111. */
  112. public function save()
  113. {
  114. $update_fields = ['avatar', 'nickname', 'mobile', 'gender', 'birthday'];
  115. $data = ['updatetime' => time()];
  116. foreach ($update_fields as $field) {
  117. $value = input("{$field}/s", '');
  118. if ($value !== '') {
  119. $data[$field] = $value;
  120. }
  121. }
  122. $user = $this->auth->getUser();
  123. if ($user->save($data)) {
  124. succ(['user' => $user->visible($this->visibleFields)]);
  125. }
  126. fail('保存失败,请重试');
  127. }
  128. /**
  129. * 账号密码注册
  130. */
  131. public function register()
  132. {
  133. if (!$username = input('username/s')) {
  134. fail('请填写登录账号');
  135. }
  136. if (!$password = input('password/s')) {
  137. fail('请填写登录密码');
  138. }
  139. if (!$nickname = input('nickname/s')) {
  140. fail('请填写昵称');
  141. }
  142. if (!$mobile = input('mobile/s')) {
  143. fail('请填写手机号码');
  144. }
  145. if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
  146. fail(__('Mobile is incorrect'));
  147. }
  148. $gender = input('gender/d', 1);
  149. // 注册
  150. $user = UserModel::fastRegister($username, $nickname, '', $gender, $password, $mobile);
  151. // 用户扩展信息
  152. $info = UserInfoModel::getUserInfo($user->id);
  153. // 接口层登录
  154. $this->auth->direct($user->id);
  155. succ([
  156. 'user' => array_merge($user->only($this->visibleFields), ['info' => $info->toArray()]),
  157. 'token' => $this->auth->getToken()
  158. ]);
  159. }
  160. /**
  161. * 账号密码登录
  162. */
  163. public function userLogin()
  164. {
  165. if (!$username = input('username/s')) {
  166. fail('请填写登录账号');
  167. }
  168. if (!$password = input('password/s')) {
  169. fail('请填写登录密码');
  170. }
  171. if (!$username || !$password) {
  172. $this->error(__('Invalid parameters'));
  173. }
  174. $user = UserModel::get(['username' => $username]);
  175. if (!$user) {
  176. fail('登录失败,账号或密码错误');
  177. }
  178. if ($user->password != $this->auth->getEncryptPassword($password, $user->salt)) {
  179. fail('登录失败,账号或密码错误');
  180. }
  181. if ($user->status != 'normal') {
  182. fail('登录失败,账号已被禁用登录');
  183. }
  184. // 用户扩展信息
  185. $info = UserInfoModel::getUserInfo($user->id);
  186. // 接口层登录
  187. $this->auth->direct($user->id);
  188. succ([
  189. 'user' => array_merge($user->only($this->visibleFields), ['info' => $info->toArray()]),
  190. 'token' => $this->auth->getToken()
  191. ]);
  192. }
  193. /**
  194. * 保存用户常用题库设置
  195. */
  196. // public function saveMyCate()
  197. // {
  198. // if (!$cate_id = input('cate_id/d', 0)) {
  199. // fail('请选择常用题库类型');
  200. // }
  201. // if (!$cate = CateModel::get($cate_id)) {
  202. // fail('题库类型不存在,请重新选择');
  203. // }
  204. //
  205. // $cate_ids = [$cate['id']];
  206. // $cate_names = [$cate['name']];
  207. //
  208. // // 上级
  209. // if ($cateParent1 = CateModel::where('id', $cate['parent_id'])->find()) {
  210. // array_unshift($cate_ids, $cateParent1['id']);
  211. // array_unshift($cate_names, $cateParent1['name']);
  212. //
  213. // // 上上级
  214. // if ($cateParent2 = CateModel::where('id', $cateParent1['parent_id'])->find()) {
  215. // array_unshift($cate_ids, $cateParent2['id']);
  216. // array_unshift($cate_names, $cateParent2['name']);
  217. // }
  218. // }
  219. //
  220. // $info = UserInfoModel::getUserInfo($this->auth->id);
  221. // $info->default_cate_ids = $cate_ids;
  222. // $info->default_cate_names = $cate_names;
  223. //
  224. // if ($info->save()) {
  225. // succ($info->toArray());
  226. // }
  227. //
  228. // fail('保存失败,请重试');
  229. // }
  230. }