UserController.php 11 KB

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