User.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <?php
  2. namespace app\api\controller;
  3. use app\common\controller\Api;
  4. use app\common\library\Ems;
  5. use app\common\library\Sms;
  6. use app\common\library\Wechat;
  7. use fast\Random;
  8. use think\Config;
  9. use think\Validate;
  10. use think\Db;
  11. /**
  12. * 会员接口
  13. */
  14. class User extends Api
  15. {
  16. protected $noNeedLogin = [''];
  17. protected $noNeedRight = '*';
  18. public function _initialize()
  19. {
  20. parent::_initialize();
  21. }
  22. //用户详细资料
  23. public function getuserinfo(){
  24. $info = $this->auth->getUserinfo();
  25. $this->success(__('success'),$info);
  26. }
  27. /**
  28. * 退出登录
  29. * @ApiMethod (POST)
  30. */
  31. public function logout()
  32. {
  33. if (!$this->request->isPost()) {
  34. $this->error(__('Invalid parameters'));
  35. }
  36. $this->auth->logout();
  37. $this->success(__('Logout successful'));
  38. }
  39. /**
  40. * 修改会员个人信息
  41. *
  42. * @ApiMethod (POST)
  43. * @param string $avatar 头像地址
  44. * @param string $username 用户名
  45. * @param string $nickname 昵称
  46. * @param string $bio 个人简介
  47. */
  48. public function profile()
  49. {
  50. $user = $this->auth->getUser();
  51. $username = $this->request->post('username');
  52. $nickname = $this->request->post('nickname');
  53. $bio = $this->request->post('bio');
  54. $avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars');
  55. if ($username) {
  56. $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find();
  57. if ($exists) {
  58. $this->error(__('Username already exists'));
  59. }
  60. $user->username = $username;
  61. }
  62. if ($nickname) {
  63. $exists = \app\common\model\User::where('nickname', $nickname)->where('id', '<>', $this->auth->id)->find();
  64. if ($exists) {
  65. $this->error(__('Nickname already exists'));
  66. }
  67. $user->nickname = $nickname;
  68. }
  69. $user->bio = $bio;
  70. $user->avatar = $avatar;
  71. $user->save();
  72. $this->success();
  73. }
  74. /**
  75. * 微信小程序登录+注册
  76. * code得到openid
  77. */
  78. public function wxmini_openid_login() {
  79. $code = input('code');
  80. if (!$code) {
  81. $this->error(__('Invalid parameters'));
  82. }
  83. $config = config('wxMiniProgram');
  84. $getopenid = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$config['appid'].'&secret='.$config['secret'].'&js_code='.$code.'&grant_type=authorization_code';
  85. $openidInfo = $this->getJson($getopenid);
  86. if(!isset($openidInfo['openid'])) {
  87. $this->error('用户openid获取失败',$openidInfo);
  88. }
  89. $openid = $openidInfo['openid'];
  90. if (!$openid) {
  91. $this->error('用户openid获取失败');
  92. }
  93. //用户信息
  94. $userInfo = Db::name('user')->where(['mini_openid'=>$openid])->find();
  95. if($userInfo) {
  96. if ($userInfo['status'] == 0) {
  97. $this->error('账号已被禁用');
  98. }
  99. if ($userInfo['status'] == -1) {
  100. $this->error('账号已被注销');
  101. }
  102. //如果已经有账号则直接登录
  103. $res = $this->auth->direct($userInfo['id']);
  104. } else {
  105. $res = $this->auth->openid_register($openid);
  106. }
  107. if($res) {
  108. $this->success("登录成功!",$this->auth->getUserinfo());
  109. } else {
  110. $this->error($this->auth->getError());
  111. }
  112. }
  113. /**
  114. * 微信小程序登录+注册
  115. * code得到注册手机号,此手机号登录+注册
  116. */
  117. public function wxmini_regmobile_login(){
  118. $code = input('code');
  119. if (!$code) {
  120. $this->error(__('Invalid parameters'));
  121. }
  122. $config = config('wxMiniProgram');
  123. $wechat = new Wechat($config['appid'],$config['secret']);
  124. $getuserphonenumber = $wechat->getuserphonenumber($code);
  125. if(!isset($getuserphonenumber['phone_info']['purePhoneNumber'])){
  126. $this->error('授权获取手机号失败');
  127. }
  128. $mobile = $getuserphonenumber['phone_info']['purePhoneNumber'];
  129. $userInfo = Db::name('user')->where('mobile',$mobile)->find();
  130. // 判断用户是否已经存在
  131. if($userInfo) { // 登录
  132. if ($userInfo['status'] != 1) {
  133. $this->error(__('Account is locked'));
  134. }
  135. //如果已经有账号则直接登录
  136. $res = $this->auth->direct($userInfo['id']);
  137. } else {
  138. $res = $this->auth->register('', '', '',$mobile, []);
  139. }
  140. if($res) {
  141. $this->success("登录成功!",$this->auth->getUserinfo());
  142. } else {
  143. $this->error($this->auth->getError());
  144. }
  145. }
  146. /**
  147. * json 请求
  148. * @param $url
  149. * @return mixed
  150. */
  151. private function getJson($url){
  152. $ch = curl_init();
  153. curl_setopt($ch, CURLOPT_URL, $url);
  154. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  155. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  156. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  157. $output = curl_exec($ch);
  158. curl_close($ch);
  159. return json_decode($output, true);
  160. }
  161. ////////////////////////////////下面的都没用到///////////////////////////////
  162. /**
  163. * 会员中心
  164. */
  165. public function index()
  166. {
  167. $this->success('', ['welcome' => $this->auth->nickname]);
  168. }
  169. /**
  170. * 会员登录
  171. *
  172. * @ApiMethod (POST)
  173. * @param string $account 账号
  174. * @param string $password 密码
  175. */
  176. public function login()
  177. {
  178. $account = $this->request->post('account');
  179. $password = $this->request->post('password');
  180. if (!$account || !$password) {
  181. $this->error(__('Invalid parameters'));
  182. }
  183. $ret = $this->auth->login($account, $password);
  184. if ($ret) {
  185. $data = ['userinfo' => $this->auth->getUserinfo()];
  186. $this->success(__('Logged in successful'), $data);
  187. } else {
  188. $this->error($this->auth->getError());
  189. }
  190. }
  191. /**
  192. * 手机验证码登录
  193. *
  194. * @ApiMethod (POST)
  195. * @param string $mobile 手机号
  196. * @param string $captcha 验证码
  197. */
  198. public function mobilelogin()
  199. {
  200. $mobile = $this->request->post('mobile');
  201. $captcha = $this->request->post('captcha');
  202. if (!$mobile || !$captcha) {
  203. $this->error(__('Invalid parameters'));
  204. }
  205. if (!Validate::regex($mobile, "^1\d{10}$")) {
  206. $this->error(__('Mobile is incorrect'));
  207. }
  208. if (!Sms::check($mobile, $captcha, 'mobilelogin')) {
  209. $this->error(__('Captcha is incorrect'));
  210. }
  211. $user = \app\common\model\User::getByMobile($mobile);
  212. if ($user) {
  213. if ($user->status != 'normal') {
  214. $this->error(__('Account is locked'));
  215. }
  216. //如果已经有账号则直接登录
  217. $ret = $this->auth->direct($user->id);
  218. } else {
  219. $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []);
  220. }
  221. if ($ret) {
  222. Sms::flush($mobile, 'mobilelogin');
  223. $data = ['userinfo' => $this->auth->getUserinfo()];
  224. $this->success(__('Logged in successful'), $data);
  225. } else {
  226. $this->error($this->auth->getError());
  227. }
  228. }
  229. /**
  230. * 注册会员
  231. *
  232. * @ApiMethod (POST)
  233. * @param string $username 用户名
  234. * @param string $password 密码
  235. * @param string $email 邮箱
  236. * @param string $mobile 手机号
  237. * @param string $code 验证码
  238. */
  239. public function register()
  240. {
  241. $username = $this->request->post('username');
  242. $password = $this->request->post('password');
  243. $email = $this->request->post('email');
  244. $mobile = $this->request->post('mobile');
  245. $code = $this->request->post('code');
  246. if (!$username || !$password) {
  247. $this->error(__('Invalid parameters'));
  248. }
  249. if ($email && !Validate::is($email, "email")) {
  250. $this->error(__('Email is incorrect'));
  251. }
  252. if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
  253. $this->error(__('Mobile is incorrect'));
  254. }
  255. $ret = Sms::check($mobile, $code, 'register');
  256. if (!$ret) {
  257. $this->error(__('Captcha is incorrect'));
  258. }
  259. $ret = $this->auth->register($username, $password, $email, $mobile, []);
  260. if ($ret) {
  261. $data = ['userinfo' => $this->auth->getUserinfo()];
  262. $this->success(__('Sign up successful'), $data);
  263. } else {
  264. $this->error($this->auth->getError());
  265. }
  266. }
  267. /**
  268. * 修改邮箱
  269. *
  270. * @ApiMethod (POST)
  271. * @param string $email 邮箱
  272. * @param string $captcha 验证码
  273. */
  274. public function changeemail()
  275. {
  276. $user = $this->auth->getUser();
  277. $email = $this->request->post('email');
  278. $captcha = $this->request->post('captcha');
  279. if (!$email || !$captcha) {
  280. $this->error(__('Invalid parameters'));
  281. }
  282. if (!Validate::is($email, "email")) {
  283. $this->error(__('Email is incorrect'));
  284. }
  285. if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) {
  286. $this->error(__('Email already exists'));
  287. }
  288. $result = Ems::check($email, $captcha, 'changeemail');
  289. if (!$result) {
  290. $this->error(__('Captcha is incorrect'));
  291. }
  292. $verification = $user->verification;
  293. $verification->email = 1;
  294. $user->verification = $verification;
  295. $user->email = $email;
  296. $user->save();
  297. Ems::flush($email, 'changeemail');
  298. $this->success();
  299. }
  300. /**
  301. * 修改手机号
  302. *
  303. * @ApiMethod (POST)
  304. * @param string $mobile 手机号
  305. * @param string $captcha 验证码
  306. */
  307. public function changemobile()
  308. {
  309. $user = $this->auth->getUser();
  310. $mobile = $this->request->post('mobile');
  311. $captcha = $this->request->post('captcha');
  312. if (!$mobile || !$captcha) {
  313. $this->error(__('Invalid parameters'));
  314. }
  315. if (!Validate::regex($mobile, "^1\d{10}$")) {
  316. $this->error(__('Mobile is incorrect'));
  317. }
  318. if (\app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find()) {
  319. $this->error(__('Mobile already exists'));
  320. }
  321. $result = Sms::check($mobile, $captcha, 'changemobile');
  322. if (!$result) {
  323. $this->error(__('Captcha is incorrect'));
  324. }
  325. $verification = $user->verification;
  326. $verification->mobile = 1;
  327. $user->verification = $verification;
  328. $user->mobile = $mobile;
  329. $user->save();
  330. Sms::flush($mobile, 'changemobile');
  331. $this->success();
  332. }
  333. /**
  334. * 第三方登录
  335. *
  336. * @ApiMethod (POST)
  337. * @param string $platform 平台名称
  338. * @param string $code Code码
  339. */
  340. public function third()
  341. {
  342. $url = url('user/index');
  343. $platform = $this->request->post("platform");
  344. $code = $this->request->post("code");
  345. $config = get_addon_config('third');
  346. if (!$config || !isset($config[$platform])) {
  347. $this->error(__('Invalid parameters'));
  348. }
  349. $app = new \addons\third\library\Application($config);
  350. //通过code换access_token和绑定会员
  351. $result = $app->{$platform}->getUserInfo(['code' => $code]);
  352. if ($result) {
  353. $loginret = \addons\third\library\Service::connect($platform, $result);
  354. if ($loginret) {
  355. $data = [
  356. 'userinfo' => $this->auth->getUserinfo(),
  357. 'thirdinfo' => $result
  358. ];
  359. $this->success(__('Logged in successful'), $data);
  360. }
  361. }
  362. $this->error(__('Operation failed'), $url);
  363. }
  364. /**
  365. * 重置密码
  366. *
  367. * @ApiMethod (POST)
  368. * @param string $mobile 手机号
  369. * @param string $newpassword 新密码
  370. * @param string $captcha 验证码
  371. */
  372. public function resetpwd()
  373. {
  374. $type = $this->request->post("type", "mobile");
  375. $mobile = $this->request->post("mobile");
  376. $email = $this->request->post("email");
  377. $newpassword = $this->request->post("newpassword");
  378. $captcha = $this->request->post("captcha");
  379. if (!$newpassword || !$captcha) {
  380. $this->error(__('Invalid parameters'));
  381. }
  382. //验证Token
  383. if (!Validate::make()->check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,30}'])) {
  384. $this->error(__('Password must be 6 to 30 characters'));
  385. }
  386. if ($type == 'mobile') {
  387. if (!Validate::regex($mobile, "^1\d{10}$")) {
  388. $this->error(__('Mobile is incorrect'));
  389. }
  390. $user = \app\common\model\User::getByMobile($mobile);
  391. if (!$user) {
  392. $this->error(__('User not found'));
  393. }
  394. $ret = Sms::check($mobile, $captcha, 'resetpwd');
  395. if (!$ret) {
  396. $this->error(__('Captcha is incorrect'));
  397. }
  398. Sms::flush($mobile, 'resetpwd');
  399. } else {
  400. if (!Validate::is($email, "email")) {
  401. $this->error(__('Email is incorrect'));
  402. }
  403. $user = \app\common\model\User::getByEmail($email);
  404. if (!$user) {
  405. $this->error(__('User not found'));
  406. }
  407. $ret = Ems::check($email, $captcha, 'resetpwd');
  408. if (!$ret) {
  409. $this->error(__('Captcha is incorrect'));
  410. }
  411. Ems::flush($email, 'resetpwd');
  412. }
  413. //模拟一次登录
  414. $this->auth->direct($user->id);
  415. $ret = $this->auth->changepwd($newpassword, '', true);
  416. if ($ret) {
  417. $this->success(__('Reset password successful'));
  418. } else {
  419. $this->error($this->auth->getError());
  420. }
  421. }
  422. }