LoginController.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: dingran
  5. * Date: 2019/2/15
  6. * Time: 下午6:56
  7. */
  8. namespace app\platform\controllers;
  9. use app\common\services\Utils;
  10. use app\frontend\modules\member\services\MemberService;
  11. use app\platform\modules\system\models\WhiteList;
  12. use app\platform\modules\user\models\OfficialWebsiteContact;
  13. use Illuminate\Foundation\Auth\AuthenticatesUsers;
  14. use Illuminate\Http\Request;
  15. use Illuminate\Support\Facades\Auth;
  16. use Illuminate\Support\Facades\Lang;
  17. use app\platform\modules\user\models\AdminUser;
  18. use app\platform\modules\system\models\SystemSetting;
  19. use app\platform\modules\application\models\UniacidApp;
  20. use app\platform\modules\application\models\AppUser;
  21. use app\common\helpers\Url;
  22. use app\common\helpers\Cache;
  23. use Illuminate\Support\Facades\DB;
  24. class LoginController extends BaseController
  25. {
  26. /*
  27. |--------------------------------------------------------------------------
  28. | Login Controller
  29. |--------------------------------------------------------------------------
  30. |
  31. | This controller handles authenticating users for the application and
  32. | redirecting them to your home screen. The controller uses a trait
  33. | to conveniently provide its functionality to your applications.
  34. |
  35. */
  36. use AuthenticatesUsers;
  37. /**
  38. * Where to redirect users after login.
  39. *
  40. * @var string
  41. */
  42. protected $redirectTo = '/admin';
  43. protected $username;
  44. private $authRole = ['operator', 'clerk'];
  45. /**
  46. * Create a new controller instance.
  47. *
  48. * @return void
  49. */
  50. public function __construct()
  51. {
  52. // $this->middleware('guest:admin', ['except' => 'logout']);
  53. }
  54. /**
  55. * 自定义字段名
  56. * 可使用
  57. * @return array
  58. */
  59. public function atributeNames()
  60. {
  61. return [
  62. 'username' => '用户名',
  63. 'password' => '密码'
  64. ];
  65. }
  66. /**
  67. * 字段规则
  68. * @return array
  69. */
  70. public function rules()
  71. {
  72. return [
  73. 'username' => 'required',
  74. 'password' => 'required',
  75. ];
  76. }
  77. /**
  78. * 重写登录视图页面
  79. * @return [type] [description]
  80. */
  81. public function showLoginForm()
  82. {
  83. return view('admin.auth.login');
  84. }
  85. /**
  86. * 自定义认证驱动
  87. * @return [type] [description]
  88. */
  89. protected function guard()
  90. {
  91. return auth()->guard('admin');
  92. }
  93. /**
  94. * 重写验证字段.
  95. *
  96. * @return string
  97. */
  98. public function username()
  99. {
  100. return 'username';
  101. }
  102. /**
  103. * Log the user out of the application.
  104. *
  105. * @param Request $request
  106. * @return \Illuminate\Http\Response
  107. */
  108. public function logout()
  109. {
  110. $this->guard('admin')->logout();
  111. request()->session()->flush();
  112. request()->session()->regenerate();
  113. Utils::removeUniacid();
  114. return $this->successJson('成功', []);
  115. }
  116. /**
  117. * 重写登录接口
  118. * @param Request $request
  119. *
  120. * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
  121. */
  122. public function login(Request $request)
  123. {
  124. $request->offsetSet('password',base64_decode($request->password));
  125. try {
  126. $this->validate($this->rules(), $request, [], $this->atributeNames());
  127. } catch (\Exception $e) {
  128. return $this->errorJson($e->getMessage());
  129. }
  130. $loginset = SystemSetting::settingLoad('loginset', 'system_loginset');
  131. if($loginset['pic_verify'] == 1)
  132. {
  133. if (!$request->captcha || app('captcha')->platformCheck($request->captcha) == false)
  134. {
  135. return $this->errorJson('图形验证码错误');
  136. }
  137. }
  138. if ($loginset['sms_verify'] == 1) {
  139. $user = AdminUser::where('username',$request->username)->with('hasOneProfile')->first();
  140. if(!$user || !\YunShop::request()->mobile)
  141. {
  142. return $this->errorJson('手机号填写错误');
  143. }
  144. //店员用户手机号码验证
  145. if ($user->hasOneProfile->mobile != \YunShop::request()->mobile && $user->type == 3)
  146. {
  147. // 区域分红(区域代理商)、酒店(hotel)、供应商、自提点(package-deliver)、分公司(subsidiary),门店
  148. $mobile = $this->getUserType($user->uid);
  149. if ($mobile == '' || $mobile != \YunShop::request()->mobile) {
  150. return $this->errorJson('手机号填写错误');
  151. }
  152. }elseif ($user->hasOneProfile->mobile != \YunShop::request()->mobile) {
  153. return $this->errorJson('手机号填写错误');
  154. }
  155. //检查验证码是否正确
  156. $check_code = app('sms')->checkAppCode($request->mobile, $request->code);
  157. if ($check_code['status'] != 1) {
  158. return $this->errorJson($check_code['json']);
  159. }
  160. }
  161. if($loginset['white_list_verify'] == 1 && !WhiteList::isWhite($request->getClientIp())) {
  162. //白名单检测,总账号(uid=1)不限制
  163. !isset($user) && $user = AdminUser::where('username',$request->username)->first();
  164. if (!$user || $user['uid'] != 1) {//没查到用户也提示这个
  165. return $this->errorJson('ip不在白名单内');
  166. }
  167. }
  168. // If the class is using the ThrottlesLogins trait, we can automatically throttle
  169. // the login attempts for this application. We'll key this by the username and
  170. // the IP address of the client making these requests into this application.
  171. $limitLogin = $this->limiter()->tooManyAttempts(
  172. $this->throttleKey($request), $loginset->login_limit_num?:5, $loginset->login_limit_time?:30
  173. );
  174. if ($limitLogin) {
  175. $this->fireLockoutEvent($request);
  176. return $this->sendLockoutResponse($request);
  177. }
  178. if ($this->attemptLogin($request,$loginset['login_expire_num'])) {
  179. return $this->sendLoginResponse($request);
  180. }
  181. // If the login attempt was unsuccessful we will increment the number of attempts
  182. // to login and redirect the user back to the login form. Of course, when this
  183. // user surpasses their maximum number of attempts they will get locked out.
  184. $this->incrementLoginAttempts($request);
  185. return $this->sendFailedLoginResponse($request);
  186. }
  187. /**
  188. * 重写登录成功json返回
  189. *
  190. * @param Request $request
  191. *
  192. * @return \Illuminate\Http\JsonResponse
  193. */
  194. public function sendLoginResponse(Request $request)
  195. {
  196. $request->session()->regenerate();
  197. $loginToken = rand(1000, 9999).time();
  198. session(['login_token'=>$loginToken]);
  199. $this->clearLoginAttempts($request);
  200. $admin_user = AdminUser::where('uid', $this->guard()->user()->uid);
  201. $admin_user->update([
  202. 'lastvisit' => time(),
  203. 'lastip' => Utils::getClientIp(),
  204. 'login_token' => $loginToken
  205. ]);
  206. $hasOneAppUser = $admin_user->first()->hasOneAppUser;
  207. if ($hasOneAppUser->role == 'clerk' || $hasOneAppUser->role == 'operator') {
  208. $sys_app = UniacidApp::getApplicationByid($hasOneAppUser->uniacid);
  209. if (!is_null($sys_app->deleted_at)) {
  210. return $this->successJson('平台已停用', ['status' => -5]);
  211. } elseif ($sys_app->validity_time !=0 && $sys_app->validity_time < mktime(0,0,0, date('m'), date('d'), date('Y'))) {
  212. return $this->successJson('平台已过期', ['status' => -5]);
  213. }
  214. }
  215. $loginset = SystemSetting::settingLoad('loginset', 'system_loginset');
  216. $pwd_remind = 0;
  217. $msg = '';
  218. //密码强度校验
  219. if ($loginset['password_verify'] == 1) {
  220. $validatePassword = validatePassword($request->password);
  221. if ($validatePassword !== true) {
  222. $pwd_remind = 2;
  223. $msg = '您当前密码过于简单,请先修改密码';
  224. }
  225. }
  226. if ($this->guard()->user()->uid !== 1) {
  227. $user = $this->guard()->user();
  228. if($loginset['password_change'] == 1){
  229. if(!$user->change_password_at)
  230. {
  231. $user->change_password_at = time();
  232. $user->save();
  233. return $this->successJson('成功', ['pwd_remind' => 1,'msg'=>'首次登陆,建议您修改密码']);
  234. }
  235. }
  236. if($user->change_password_at+6912000 <= time() && $user->change_remind == 0 && $loginset['force_change_pwd'] == 1)
  237. {
  238. $user->change_remind = 1;
  239. $user->save();
  240. return $this->successJson('成功', ['pwd_remind' => 1,'msg'=>'您已长时间未修改密码,请您先修改密码,否则账号将在10天后冻结']);
  241. }
  242. $account = AppUser::getAccount($this->guard()->user()->uid);
  243. if (!is_null($account) && in_array($account->role, $this->authRole)) {
  244. Utils::addUniacid($account->uniacidb);
  245. \YunShop::app()->uniacid = $account->uniacid;
  246. self::addLogsAction($this->guard()->user()->uid,'其他用户',2);
  247. return $this->successJson('成功', ['url' => Url::absoluteWeb('index.index', ['uniacid' => $account->uniacid,'pwd_remind'=>$pwd_remind])]);
  248. }
  249. }
  250. self::addLogsAction($this->guard()->user()->uid,'超级管理员',1);
  251. return $this->successJson('成功',['pwd_remind'=>$pwd_remind,'msg'=>$msg]);
  252. }
  253. /**
  254. * 重写登录失败json返回
  255. *
  256. * @param Request $request
  257. *
  258. * @return \Illuminate\Http\RedirectResponse
  259. */
  260. public function sendFailedLoginResponse(Request $request)
  261. {
  262. return $this->errorJson(Lang::get('auth.failed'), []);
  263. }
  264. /**
  265. * 重写登录失败次数限制
  266. *
  267. * @param \Illuminate\Http\Request $request
  268. * @return \Illuminate\Http\RedirectResponse
  269. */
  270. protected function sendLockoutResponse(Request $request)
  271. {
  272. $seconds = $this->limiter()->availableIn(
  273. $this->throttleKey($request)
  274. );
  275. $message = Lang::get('auth.throttle', ['seconds' => $seconds]);
  276. return $this->errorJson($message);
  277. }
  278. /**
  279. * Attempt to log the user into the application.
  280. *
  281. *
  282. * @param \Illuminate\Http\Request $request
  283. * @return bool
  284. */
  285. protected function attemptLogin(Request $request,$minutes = 0)
  286. {
  287. $result = $this->guard()->attempt(
  288. $this->credentials($request),1
  289. );
  290. if ($result) {
  291. $minutes = $minutes ?? 2628000;
  292. $user = $this->guard()->getuser();
  293. $value = $user->getAuthIdentifier().'|'.$user->getRememberToken().'|'.$user->getAuthPassword();
  294. $this->guard()->getCookieJar()->queue($this->guard()->getRecallerName(),$value,$minutes);
  295. }
  296. return $result;
  297. }
  298. public function site()
  299. {
  300. $default = [
  301. 'name' => "芸众商城管理系统",
  302. 'site_logo' => yz_tomedia("/static/images/site_logo.png"),
  303. 'title_icon' => yz_tomedia("/static/images/title_icon.png"),
  304. 'advertisement' => yz_tomedia("/static/images/advertisement.jpg"),
  305. 'information' => '<p>&copy; 2019&nbsp;<a href="https://www.yunzmall.com/" target=\"_blank\" rel=\"noopener\">Yunzhong.</a>&nbsp;All Rights Reserved. 广州市芸众信息科技有限公司&nbsp;&nbsp;<a href="http://www.miit.gov.cn/" target="_blank\" rel="noopener\">&nbsp;粤ICP备17018310号-1</a>&nbsp;Powered by Yunzhong&nbsp;</p> <p><a href="https://www.yunzmall.com/plugins/shop_server/knowledge/home?i=10" target="_blank\" rel="noopener\">系统使用教程:www.yunzmall.com</a>&nbsp; &nbsp;&nbsp;<a href="https://www.yunzmall.com/plugins/shop_server/videoList?i=10&type=5" target="_blank\" rel="noopener\">视频教程</a></p>'
  306. ];
  307. $copyright = SystemSetting::settingLoad('copyright', 'system_copyright');
  308. $copyright['name'] = !isset($copyright['name']) ? $default['name'] : $copyright['name'];
  309. $copyright['site_logo'] = !isset($copyright['site_logo']) ? $default['site_logo'] : $copyright['site_logo'];
  310. $copyright['title_icon'] = !isset($copyright['title_icon']) ? $default['title_icon'] : $copyright['title_icon'];
  311. $copyright['advertisement'] = !isset($copyright['advertisement']) ? $default['advertisement'] : $copyright['advertisement'];
  312. $copyright['information'] = !isset($copyright['information']) ? $default['information'] : $copyright['information'];
  313. $loginset = SystemSetting::settingLoad('loginset', 'system_loginset');
  314. $copyright['register_open'] = $loginset['register_open'] ?: 0;
  315. if($loginset['pic_verify'] == 1)
  316. {
  317. $copyright['captcha']['status'] = true;
  318. $captcha = app('captcha');
  319. $captcha_base64 = $captcha->create('default', true,true);
  320. $copyright['captcha']['img'] = $captcha_base64['img'];
  321. }else{
  322. $copyright['captcha']['status'] = false;
  323. }
  324. if($loginset['sms_verify'] == 1)
  325. {
  326. $copyright['sms']['status'] = true;
  327. }else{
  328. $copyright['sms']['status'] = false;
  329. }
  330. if ($copyright) {
  331. return $this->successJson('成功', $copyright);
  332. } else {
  333. return $this->errorJson('没有检测到数据', '');
  334. }
  335. }
  336. public function loginCode()
  337. {
  338. $mobile = request()->mobile;
  339. $state = \YunShop::request()->state ? : '86';
  340. if(!request()->username)
  341. {
  342. return $this->errorJson('请先完善账号信息');
  343. }
  344. $user = AdminUser::where('username',request()->username)->with('hasOneProfile')->first();
  345. if(!$user || !$mobile)
  346. {
  347. return $this->errorJson('手机号填写错误');
  348. }
  349. if ($user->hasOneProfile->mobile != $mobile)
  350. {
  351. if ($user->type != 3)
  352. {
  353. return $this->errorJson('手机号填写错误');
  354. }elseif ($this->getUserType($user->uid) != $mobile) {
  355. return $this->errorJson('手机号填写错误');
  356. }
  357. }
  358. $code = rand(1000, 9999);
  359. Cache::put($mobile.'_code', $code, 60 * 10);
  360. return (new ResetpwdController())->sendSmsV2($mobile, $code, $state,'login',3);
  361. }
  362. public function refreshPic()
  363. {
  364. $captcha = app('captcha');
  365. $captcha_base64 = $captcha->create('default', true,true);
  366. return $this->successJson('成功', $captcha_base64['img']);
  367. }
  368. //添加登录记录
  369. public static function addLogsAction($userId, $detail_remark, $admin_type)
  370. {
  371. $detail_parameter = array(2, 0, $detail_remark, 0);
  372. list($other, $member_id, $remark, $uniacid) = $detail_parameter;//依次:其他管理员类型,默认会员ID,默认类型
  373. $username = DB::table('yz_admin_users')->where('uid', $userId)->value('username');
  374. //其他管理员
  375. if ($admin_type == $other) {
  376. $userTable = 'uni_account_users';
  377. if (config('app.framework') == 'platform') {
  378. $userTable = 'yz_app_user';
  379. }
  380. //其他管理员所属公众号
  381. $uniacid = DB::table($userTable)->where('uid', $userId)->value('uniacid');
  382. $uid_arr = ['yz_supplier'];//uid
  383. $user_id_arr = ['yz_user_role', 'yz_area_dividend_agent'];//user_id
  384. $user_uid_arr = ['yz_package_deliver', 'yz_subsidiary', 'yz_store', 'yz_hotel'];//user_uid
  385. $all_arr = array_merge($uid_arr, $user_id_arr, $user_uid_arr);
  386. //区分表的账号类型和会员id字段
  387. $admin_type = [
  388. 'yz_user_role' => ['remark' => '操作员', 'user_type' => ''],
  389. 'yz_supplier' => ['remark' => '供应商', 'user_type' => 'member_id'],
  390. 'yz_store' => ['remark' => '门店', 'user_type' => 'uid'],
  391. 'yz_hotel' => ['remark' => '酒店', 'user_type' => 'uid'],
  392. 'yz_area_dividend_agent' => ['remark' => '区域代理', 'user_type' => 'member_id'],
  393. 'yz_package_deliver' => ['remark' => '自提点', 'user_type' => 'uid'],
  394. 'yz_subsidiary' => ['remark' => '分公司', 'user_type' => 'uid'],
  395. ];
  396. $column = '';
  397. foreach ($all_arr as $item) {
  398. if ($item == $uid_arr[0]) {
  399. $column = 'uid';
  400. } elseif (in_array($item, $user_id_arr)) {
  401. $column = 'user_id';
  402. } elseif (in_array($item, $user_uid_arr)) {
  403. $column = 'user_uid';
  404. }
  405. if ($column && \Schema::hasTable($item)) {
  406. $hasAdmin = DB::table($item)->where($column, $userId)->first();
  407. if ($hasAdmin) {
  408. $remark = $admin_type[$item]['remark'];
  409. $user_type = $admin_type[$item]['user_type'];
  410. $member_id = $hasAdmin[$user_type] ?: 0;
  411. }
  412. }
  413. }
  414. }
  415. //添加登录记录
  416. DB::table('yz_admin_logs')->insert([
  417. 'uniacid' => $uniacid,
  418. 'admin_uid' => $userId ?: 0,
  419. 'remark' => $remark,
  420. 'ip' => Utils::getClientIp() ?: 0,
  421. 'member_id' => $member_id,
  422. 'username' => $username,
  423. 'created_at' => time(),
  424. 'updated_at' => time()
  425. ]);
  426. }
  427. /**
  428. * 获取用户身份类型(区域分红(区域代理商)、酒店(hotel)、供应商、自提点(package-deliver)、分公司(subsidiary),门店)
  429. */
  430. public function getUserType($userId)
  431. {
  432. $mobile = '';
  433. if (\Schema::hasTable('yz_store'))
  434. {
  435. $member_id = DB::table('yz_store')->where('user_uid',$userId)->value('uid'); //门店
  436. $mobile = DB::table('yz_store_apply')->where('uid',$member_id)->value('mobile'); //门店
  437. }
  438. if (\Schema::hasTable('yz_hotel') && !$mobile) {
  439. $mobile = DB::table('yz_hotel')->where('user_uid',$userId)->value('mobile'); //酒店
  440. }
  441. if (\Schema::hasTable('yz_area_dividend_agent') && !$mobile) {
  442. $mobile = DB::table('yz_area_dividend_agent')->where('user_id',$userId)->value('mobile'); //区域分红
  443. }
  444. if (\Schema::hasTable('yz_supplier') && !$mobile) {
  445. $mobile = DB::table('yz_supplier')->where('uid',$userId)->value('mobile'); //供应商
  446. }
  447. if (\Schema::hasTable('yz_package_deliver') && !$mobile) {
  448. $mobile = DB::table('yz_package_deliver')->where('user_uid',$userId)->value('deliver_mobile'); //自提点
  449. }
  450. if (\Schema::hasTable('yz_subsidiary') && !$mobile) {
  451. $mobile = DB::table('yz_subsidiary')->where('user_uid',$userId)->value('mobile'); //分公司
  452. }
  453. return $mobile;
  454. }
  455. }