Account.php 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <?php
  2. namespace app\api\controller;
  3. use ba\Date;
  4. use ba\Captcha;
  5. use ba\Random;
  6. use think\facade\Db;
  7. use app\common\model\User;
  8. use app\common\facade\Token;
  9. use app\common\model\UserScoreLog;
  10. use app\common\model\UserMoneyLog;
  11. use app\common\controller\Frontend;
  12. use think\db\exception\PDOException;
  13. use think\exception\ValidateException;
  14. use app\api\validate\Account as AccountValidate;
  15. use think\facade\Validate;
  16. class Account extends Frontend
  17. {
  18. protected $noNeedLogin = ['retrievePassword'];
  19. protected $model = null;
  20. public function initialize()
  21. {
  22. parent::initialize();
  23. }
  24. public function overview()
  25. {
  26. $sevenDays = Date::unixtime('day', -6);
  27. $score = $money = $days = [];
  28. for ($i = 0; $i < 7; $i++) {
  29. $days[$i] = date("Y-m-d", $sevenDays + ($i * 86400));
  30. $tempToday0 = strtotime($days[$i]);
  31. $temptoday24 = strtotime('+1 day', $tempToday0) - 1;
  32. $score[$i] = UserScoreLog::where('user_id', $this->auth->id)
  33. ->where('createtime', 'BETWEEN', $tempToday0 . ',' . $temptoday24)
  34. ->sum('score');
  35. $userMoneyTemp = UserMoneyLog::where('user_id', $this->auth->id)
  36. ->where('createtime', 'BETWEEN', $tempToday0 . ',' . $temptoday24)
  37. ->sum('money');
  38. $money[$i] = bcdiv($userMoneyTemp, 100, 2);
  39. }
  40. $this->success('', [
  41. 'days' => $days,
  42. 'score' => $score,
  43. 'money' => $money,
  44. ]);
  45. }
  46. public function profile()
  47. {
  48. if ($this->request->isPost()) {
  49. $data = $this->request->only(['id', 'avatar', 'username', 'nickname', 'gender', 'birthday', 'motto']);
  50. if (!isset($data['birthday'])) $data['birthday'] = null;
  51. Db::startTrans();
  52. try {
  53. $validate = new AccountValidate();
  54. $validate->scene('edit')->check($data);
  55. $this->auth->getUser()->where('id', $this->auth->id)->update($data);
  56. Db::commit();
  57. } catch (ValidateException|PDOException $e) {
  58. Db::rollback();
  59. $this->error($e->getMessage());
  60. }
  61. $this->success(__('Data updated successfully~'));
  62. }
  63. $this->success('', [
  64. 'accountVerificationType' => get_account_verification_type()
  65. ]);
  66. }
  67. /**
  68. * 通过手机号或邮箱验证账户
  69. * 此处检查的验证码是通过 api/Ems或api/Sms发送的
  70. * 验证成功后,向前端返回一个 email-pass Token或着 mobile-pass Token
  71. * 在 changBind 方法中,通过 pass Token来确定用户已经通过了账户验证(用户未绑定邮箱/手机时通过账户密码验证)
  72. */
  73. public function verification()
  74. {
  75. $captcha = new Captcha();
  76. $params = $this->request->only(['type', 'captcha']);
  77. if ($captcha->check($params['captcha'], ($params['type'] == 'email' ? $this->auth->email : $this->auth->mobile) . "user_{$params['type']}_verify")) {
  78. $uuid = Random::uuid();
  79. Token::set($uuid, $params['type'] . '-pass', $this->auth->id, 600);
  80. $this->success('', [
  81. 'type' => $params['type'],
  82. 'accountVerificationToken' => $uuid,
  83. ]);
  84. }
  85. $this->error(__('Please enter the correct verification code'));
  86. }
  87. /**
  88. * 修改绑定信息(手机号、邮箱)
  89. * 通过 pass Token来确定用户已经通过了账户验证,也就是以上的 verification 方法,同时用户未绑定邮箱/手机时通过账户密码验证
  90. */
  91. public function changeBind()
  92. {
  93. $captcha = new Captcha();
  94. $params = $this->request->only(['type', 'captcha', 'email', 'mobile', 'accountVerificationToken', 'password']);
  95. $user = $this->auth->getUser();
  96. if ($user[$params['type']]) {
  97. if (!Token::check($params['accountVerificationToken'], $params['type'] . '-pass', $user->id, false)) {
  98. $this->error(__('You need to verify your account before modifying the binding information'));
  99. }
  100. } else {
  101. // 验证账户密码
  102. if (!isset($params['password']) || $user->password != encrypt_password($params['password'], $user->salt)) {
  103. $this->error(__('Password error'));
  104. }
  105. }
  106. // 检查验证码
  107. if ($captcha->check($params['captcha'], $params[$params['type']] . "user_change_{$params['type']}")) {
  108. if ($params['type'] == 'email') {
  109. $validate = Validate::rule(['email' => 'require|email|unique:user'])->message([
  110. 'email.require' => 'email format error',
  111. 'email.email' => 'email format error',
  112. 'email.unique' => 'email is occupied',
  113. ]);
  114. if (!$validate->check(['email' => $params['email']])) {
  115. $this->error(__($validate->getError()));
  116. }
  117. $user->email = $params['email'];
  118. } elseif ($params['type'] == 'mobile') {
  119. $validate = Validate::rule(['mobile' => 'require|mobile|unique:user'])->message([
  120. 'mobile.require' => 'mobile format error',
  121. 'mobile.mobile' => 'mobile format error',
  122. 'mobile.unique' => 'mobile is occupied',
  123. ]);
  124. if (!$validate->check(['mobile' => $params['mobile']])) {
  125. $this->error(__($validate->getError()));
  126. }
  127. $user->mobile = $params['mobile'];
  128. }
  129. Token::delete($params['accountVerificationToken']);
  130. $user->save();
  131. $this->success();
  132. }
  133. $this->error(__('Please enter the correct verification code'));
  134. }
  135. public function changePassword()
  136. {
  137. if ($this->request->isPost()) {
  138. $params = $this->request->only(['oldPassword', 'newPassword']);
  139. if (!$this->auth->checkPassword($params['oldPassword'])) {
  140. $this->error(__('Old password error'));
  141. }
  142. Db::startTrans();
  143. try {
  144. $validate = new AccountValidate();
  145. $validate->scene('changePassword')->check(['password' => $params['newPassword']]);
  146. $this->auth->getUser()->resetPassword($this->auth->id, $params['newPassword']);
  147. Db::commit();
  148. } catch (ValidateException|PDOException $e) {
  149. Db::rollback();
  150. $this->error($e->getMessage());
  151. }
  152. $this->auth->logout();
  153. $this->success(__('Password has been changed, please login again~'));
  154. }
  155. }
  156. public function integral()
  157. {
  158. $limit = $this->request->request('limit');
  159. $integralModel = new UserScoreLog();
  160. $res = $integralModel->where('user_id', $this->auth->id)
  161. ->order('createtime desc')
  162. ->paginate($limit);
  163. $this->success('', [
  164. 'list' => $res->items(),
  165. 'total' => $res->total(),
  166. ]);
  167. }
  168. public function balance()
  169. {
  170. $limit = $this->request->request('limit');
  171. $moneyModel = new UserMoneyLog();
  172. $res = $moneyModel->where('user_id', $this->auth->id)
  173. ->order('createtime desc')
  174. ->paginate($limit);
  175. $this->success('', [
  176. 'list' => $res->items(),
  177. 'total' => $res->total(),
  178. ]);
  179. }
  180. public function retrievePassword()
  181. {
  182. $params = $this->request->only(['type', 'account', 'captcha', 'password']);
  183. try {
  184. $validate = new AccountValidate();
  185. $validate->scene('retrievePassword')->check($params);
  186. } catch (ValidateException $e) {
  187. $this->error($e->getMessage());
  188. }
  189. if ($params['type'] == 'email') {
  190. $user = User::where('email', $params['account'])->find();
  191. } else {
  192. $user = User::where('mobile', $params['account'])->find();
  193. }
  194. if (!$user) {
  195. $this->error(__('Account does not exist~'));
  196. }
  197. $captchaObj = new Captcha();
  198. if (!$captchaObj->check($params['captcha'], $params['account'] . 'user_retrieve_pwd')) {
  199. $this->error(__('Please enter the correct verification code'));
  200. }
  201. if ($user->resetPassword($user->id, $params['password'])) {
  202. $this->success(__('Password has been changed~'));
  203. } else {
  204. $this->error(__('Failed to modify password, please try again later~'));
  205. }
  206. }
  207. }