UserController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. <?php
  2. namespace App\Http\Controllers\Account;
  3. use App\Http\Controllers\Controller;
  4. use App\Models\EmailToken;
  5. use App\Models\User;
  6. use App\Repositories\UserRepository;
  7. use App\Services\CaptchaService;
  8. use App\Services\CreditService;
  9. use App\Services\SmsService;
  10. use Illuminate\Contracts\Auth\Guard;
  11. use Illuminate\Http\Request;
  12. use Illuminate\Support\Facades\Hash;
  13. class UserController extends Controller
  14. {
  15. protected $auth;
  16. protected $userRepository;
  17. protected $captchaService;
  18. public function __construct(Guard $auth,UserRepository $userRepository,CaptchaService $captchaService){
  19. $this->auth = $auth;
  20. $this->userRepository = $userRepository;
  21. $this->captchaService = $captchaService;
  22. }
  23. public function login(Request $request){
  24. /*登录表单处理*/
  25. if($request->isMethod('post'))
  26. {
  27. $request->flashOnly('email');
  28. $validateRules = [
  29. 'email' => 'required|min:2|max:128',
  30. 'password' => 'required|min:6'
  31. ];
  32. if( Setting()->get('code_login') == 1){
  33. $this->captchaService->setValidateRules('code_login', $validateRules);
  34. }
  35. /*表单数据校验*/
  36. $this->validate($request,$validateRules);
  37. /*只接收email和password的值*/
  38. $credentials = [
  39. 'password' => $request->input('password')
  40. ];
  41. // if(is_email($request->input('email'))){
  42. $credentials['email'] = $request->input('email');
  43. // }else{
  44. // $credentials['mobile'] = $request->input('email');
  45. // }
  46. /*根据邮箱地址和密码进行认证*/
  47. if ($this->auth->attempt($credentials, $request->has('remember')))
  48. {
  49. if($this->credit($request->user()->id,'login',Setting()->get('coins_login'),Setting()->get('credits_login'))){
  50. $message = '登陆成功! '.get_credit_message(Setting()->get('credits_login'),Setting()->get('coins_login'));
  51. return $this->success(route('website.index'),$message,true);
  52. }
  53. session_start();
  54. $_SESSION['login_time'] = time();
  55. /*认证成功后跳转到首页*/
  56. return $this->success(route('auth.doing.index'),'登陆成功!',true);
  57. }
  58. /*登录失败后跳转到首页,并提示错误信息*/
  59. return redirect(route('auth.user.login'))
  60. ->withInput($request->only('email', 'remember'))
  61. ->withErrors([
  62. 'password' => '用户名或密码错误,请核实!',
  63. ]);
  64. }
  65. return view("theme::account.login");
  66. }
  67. /**
  68. * 用户注册入口
  69. * @param Request $request
  70. * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
  71. */
  72. public function register(Request $request)
  73. {
  74. /*注册是否开启*/
  75. if(!Setting()->get('register_open',1)){
  76. return $this->showErrorMsg(route('website.index'),'管理员已关闭了网站的注册功能!');
  77. }
  78. /*防灌水检查*/
  79. if( Setting()->get('register_limit_num') > 0 ){
  80. $registerCount = $this->counter('register_number_'.md5($request->ip()));
  81. if( $registerCount >= Setting()->get('register_limit_num')){
  82. return $this->showErrorMsg(route('website.index'),'您的当前的IP已经超过当日最大注册数目,如有疑问请联系管理员');
  83. }
  84. }
  85. /*注册表单处理*/
  86. if($request->isMethod('post'))
  87. {
  88. $request->flashExcept(['password','password_confirmation']);
  89. /*表单数据校验*/
  90. $validateRules = [
  91. 'name' => 'required|min:2|max:100|unique:users',
  92. 'password' => 'required|confirmed|min:6|max:16',
  93. ];
  94. if(Setting()->get('register_type') == 'email'){
  95. $validateRules['email'] = 'required|email|max:255|unique:users';
  96. }else{
  97. $validateRules['mobile'] = 'required|regex:/^1[3456789]\d{9}$/|unique:users';
  98. $validateRules['code'] = 'required|min:4|:max:8';
  99. }
  100. if( Setting()->get('code_register') == 1){
  101. $this->captchaService->setValidateRules('code_register', $validateRules);
  102. }
  103. $this->validate($request,$validateRules);
  104. $formData = $request->all();
  105. $formData['status'] = 0;
  106. $formData['visit_ip'] = $request->getClientIp();
  107. if( Setting()->get('register_type') == 'mobile' ){
  108. if( !SmsService::verifySmsCode($formData['mobile'],$request->input('code')) ) {
  109. return view("theme::account.register")->withErrors(['code'=>'短信验证码错误']);
  110. }
  111. $formData['status'] = 1;
  112. }
  113. $user = $this->userRepository->register($formData);
  114. $user->attachRole(2); //默认注册为普通用户角色
  115. $this->auth->login($user);
  116. $message = '注册成功!';
  117. if($this->credit($request->user()->id,'register',Setting()->get('coins_register'),Setting()->get('credits_register'))){
  118. $message .= get_credit_message(Setting()->get('credits_register'),Setting()->get('coins_register'));
  119. }
  120. if(Setting()->get('register_type')=='email'){
  121. /*发送邮箱验证邮件*/
  122. $emailToken = EmailToken::create([
  123. 'email' => $user->email,
  124. 'token' => EmailToken::createToken(),
  125. 'action'=> 'register'
  126. ]);
  127. if($emailToken){
  128. $subject = '欢迎注册'.Setting()->get('website_name').',请激活您注册的邮箱!';
  129. $content = "「".$request->user()->name."」您好,请激活您在 ".Setting()->get('website_name')." 的注册邮箱!<br /> 请在1小时内点击该链接激活注册账号 → ".route('auth.email.verifyToken',['action'=>$emailToken->action,'token'=>$emailToken->token])."<br />如非本人操作,请忽略此邮件!";
  130. $this->sendEmail($emailToken->email,$subject,$content);
  131. }
  132. }
  133. /*记录注册ip*/
  134. $this->counter('register_number_'.md5($request->ip()) , 1,86400 );
  135. return $this->success(route('website.index'),$message);
  136. }
  137. return view("theme::account.register");
  138. }
  139. /*忘记密码*/
  140. public function forgetPassword()
  141. {
  142. return view("theme::account.forgetPassword");
  143. }
  144. /*通过邮件方式找回密码*/
  145. public function findByEmail(Request $request){
  146. if($request->isMethod('post'))
  147. {
  148. $request->flashOnly('email');
  149. /*表单数据校验*/
  150. $this->validate($request, [
  151. 'email' => 'required|email|exists:users',
  152. 'captcha' => 'required|captcha'
  153. ]);
  154. $emailToken = EmailToken::create([
  155. 'email' => $request->input('email'),
  156. 'token' => EmailToken::createToken(),
  157. 'action'=> 'findPassword'
  158. ]);
  159. if($emailToken){
  160. $subject = Setting()->get('website_name').' 找回密码通知';
  161. $content = "如果您在 ".Setting()->get('website_name')."的密码丢失,请点击下方链接找回 → ".route('auth.user.findPassword',['token'=>$emailToken->token])."<br />如非本人操作,请忽略此邮件!";
  162. $this->sendEmail($emailToken->email,$subject,$content);
  163. }
  164. return view("theme::account.findByEmail")->with('success','ok')->with('email',$request->input('email'));
  165. }
  166. return view("theme::account.findByEmail");
  167. }
  168. /*通过手机验证码找回密码*/
  169. public function findByMobile(Request $request){
  170. if($request->isMethod('post')){
  171. $this->validate($request, [
  172. 'mobile' => 'required|regex:/^1[34578]\d{9}$/|exists:users',
  173. 'code' => 'required|min:4|max:6',
  174. 'password' => 'required|min:6|max:32'
  175. ]);
  176. $mobile = $request->input('mobile');
  177. $code = $request->input('code');
  178. if( !SmsService::verifySmsCode($mobile,$code) ){
  179. return view("theme::account.findByMobile")->withErrors(['code'=>'验证码错误']);
  180. }
  181. $user = User::where('mobile','=',$mobile)->first();
  182. if(!$user){
  183. return view("theme::account.findByMobile")->withErrors(['mobile'=>'手机号不存在']);
  184. }
  185. $user->password = Hash::make($request->input('password'));
  186. $user->save();
  187. return $this->success(route('auth.user.login'),'密码修改成功,请重新登录');
  188. }
  189. return view("theme::account.findByMobile");
  190. }
  191. public function findPassword($token,Request $request)
  192. {
  193. if($request->isMethod('post')){
  194. $this->validate($request, [
  195. 'password' => 'required|min:6|max:32',
  196. 'captcha' => 'required|captcha'
  197. ]);
  198. $emailToken = EmailToken::where('action','=','findPassword')->where('token','=',$token)->first();
  199. if(!$emailToken){
  200. return $this->error(route('website.ask'),'token信息不存在,请重新找回');
  201. }
  202. if($emailToken->created_at->diffInMinutes() > 60){
  203. return $this->error(route('website.ask'),'token信息已失效,请重新找回');
  204. }
  205. $user = User::where('email','=',$emailToken->email)->first();
  206. if(!$user){
  207. return $this->error(route('website.ask'),'用户不存在或已被删除');
  208. }
  209. $user->password = Hash::make($request->input('password'));
  210. $user->save();
  211. EmailToken::clear($user->email,'findPassword');
  212. return $this->success(route('auth.user.login'),'密码修改成功,请重新登录');
  213. }
  214. return view("theme::account.findPassword")->with('token',$token);
  215. }
  216. /*每日签到*/
  217. public function sign(Request $request){
  218. if(!Setting()->get('open_user_sign')){
  219. abort(404);
  220. }
  221. $loginUser = $request->user();
  222. if($loginUser->isSigned()){
  223. return $this->error(route('website.index'),'今日已签到,不能重复签到');
  224. }
  225. $message = '签到成功!';
  226. if(CreditService::create($loginUser->id, 'sign', Setting()->get('coins_sign'),Setting()->get('credits_sign'))){
  227. $message .= get_credit_message(Setting()->get('credits_sign'),Setting()->get('coins_sign'));
  228. }
  229. return $this->success(route('website.index'),$message);
  230. }
  231. /**
  232. * 用户登出
  233. */
  234. public function logout(){
  235. setcookie("token",0,time()-7200,"/",".nxjiewei.com");
  236. session_start();
  237. unset($_SESSION['login_time']);
  238. $this->auth->logout();
  239. return redirect()->to(route('website.index'));
  240. }
  241. }