Login.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <?php
  2. namespace App\Http\Controllers\Manager;
  3. use App\Models\Manager\AdminUser;
  4. use App\Http\Requests\Manager\Login as Request;
  5. use App\Models\Manager\AuthRule;
  6. use App\Facades\Servers\Encrypts\AccessToken;
  7. use App\Models\Manager\Personnel\Employee as EmployeeModel;
  8. use App\Facades\Servers\Sms\VerifyCode as Sms;
  9. use App\Models\Manager\Personnel\EmployeeOpenid as EmployeeOpenidModel;
  10. use App\Servers\Wechat\WeChatWebApp;
  11. use App\Models\Manager\Personnel\RolesAuthRule as RolesAuthRuleModel;
  12. use Illuminate\Support\Facades\Cache;
  13. use Illuminate\Support\Facades\DB;
  14. /**
  15. * 管理后台登录控制器
  16. * @author 唐远望
  17. * @version 1.0
  18. * @date 2025-12-02
  19. *
  20. * */
  21. class Login extends Manager
  22. {
  23. /**
  24. * 登录方法 /manager/login/index
  25. * @author 唐远望
  26. * @version 1.0
  27. * @date 2025-12-02
  28. * @param string username 登录账号
  29. * @param string password 登录密码
  30. *
  31. * */
  32. public function index(Request $Request, AdminUser $AdminUser, AuthRule $AuthRule, EmployeeModel $EmployeeModel, RolesAuthRuleModel $RolesAuthRuleModel)
  33. {
  34. // 验证规则
  35. $Request->scene('login')->validate();
  36. // 接收数据
  37. $username = $Request->input('username', '');
  38. // 接收数据
  39. $password = $Request->input('password', '');
  40. if (strtolower($username) == 'admin') {
  41. // 查询用户
  42. $admin = $AdminUser->orWhere('username', $username)->first(['uid', 'username', 'phone', 'status', 'password', 'insert_time', 'update_time']);
  43. // 用户不存在
  44. if (!$admin) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  45. // 用户不存在
  46. if ($admin['status']) return json_send(['code' => 'error', 'msg' => '该账号已停用']);
  47. // 转数组
  48. $admin = $admin->toArray();
  49. // 比对密码
  50. if (md5($password) != $admin['password']) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  51. // 登录
  52. $accessToken = $AdminUser->Login($admin['uid'], 'manager');
  53. // 比对密码
  54. if (isset($accessToken['error'])) return json_send(['code' => 'error', 'msg' => '登录失败', 'data' => $accessToken['data']]);
  55. // 获取权限列表
  56. $accessToken['username'] = $admin['username'];
  57. $accessToken['is_system_admin'] = 1;
  58. // 获取权限列表
  59. } else {
  60. $admin = $EmployeeModel->where('employee_code', $username)->first(['company_id', 'id as uid', 'name as username', 'mobile as phone', 'status', 'password', 'insert_time', 'update_time']);
  61. // 用户不存在
  62. if (!$admin) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  63. // 用户不存在
  64. if ($admin['status']) return json_send(['code' => 'error', 'msg' => '该账号已停用']);
  65. // 转数组
  66. $admin = $admin->toArray();
  67. // 比对密码
  68. if (md5($password) != $admin['password']) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  69. // 登录
  70. $accessToken = $EmployeeModel->Login($admin['uid'], $admin['company_id'], 'manager');
  71. // 比对密码
  72. if (isset($accessToken['error'])) return json_send(['code' => 'error', 'msg' => '登录失败', 'data' => $accessToken['data']]);
  73. // 获取权限列表
  74. $accessToken['username'] = $admin['username'];
  75. $accessToken['is_system_admin'] = 0;
  76. }
  77. // 表单令牌
  78. return json_send(['code' => 'success', 'msg' => '登录成功', 'data' => $accessToken]);
  79. }
  80. /**
  81. * 获取用户页面权限 /manager/login/auth_rules'
  82. * @author 唐远望
  83. * @version 1.0
  84. * @date 2026-01-30
  85. * @param string username 登录账号
  86. * @param string password 登录密码
  87. *
  88. */
  89. public function auth_rules(Request $Request, AuthRule $AuthRule, RolesAuthRuleModel $RolesAuthRuleModel)
  90. {
  91. $access_token = $Request->input('access_token', '');
  92. if (!isset($access_token)) return json_send(['code' => 'error', 'msg' => '缺少参数']);
  93. $auth_rules = [];
  94. if ($access_token['is_admin'] == 0) {
  95. $auth_rules = $RolesAuthRuleModel->getAuthList($access_token['uid'], '0', 'manager');
  96. } else {
  97. $auth_rules = $AuthRule->getAuthList($access_token['uid'], '1', 'manager');
  98. }
  99. return json_send(['code' => 'success', 'msg' => '获取成功', 'data' => $auth_rules]);
  100. }
  101. /**
  102. * 登录方法 /manager/login/out
  103. * @author 唐远望
  104. * @version 1.0
  105. * @date 2025-12-02
  106. * @param string username 登录账号
  107. * @param string password 登录密码
  108. *
  109. * */
  110. public function out(Request $Request, AdminUser $AdminUser, EmployeeModel $EmployeeModel)
  111. {
  112. $token = $Request->input('access_token_manager', '');
  113. // 解码
  114. $userInfo = AccessToken::decode($token);
  115. // 验证规则
  116. $uid = $userInfo['uid'];
  117. $is_admin = $userInfo['is_admin'];
  118. if ($is_admin == '1') {
  119. // 退出登录
  120. $AdminUser->LoginOut($uid, 'manager');
  121. } else {
  122. $EmployeeModel->LoginOut($uid, 'manager');
  123. }
  124. // 表单令牌
  125. return json_send(['code' => 'success', 'msg' => '退出成功', 'data' => '']);
  126. }
  127. /**
  128. * 手机号码登录 /manager/login/mobile
  129. * @author 唐远望
  130. * @version 1.0
  131. * @date 2025-12-04
  132. * @param string mobile 手机号码
  133. * @param string password 登录密码
  134. *
  135. */
  136. public function mobile(Request $Request, AuthRule $AuthRule, EmployeeModel $EmployeeModel)
  137. {
  138. // 验证规则
  139. $Request->scene('mobile')->validate();
  140. // 接收数据
  141. $phone = $Request->input('phone', '');
  142. // 接收数据
  143. $password = $Request->input('password', '');
  144. // 查询用户
  145. $admin = $EmployeeModel->where('mobile', $phone)->first(['company_id', 'id as uid', 'name as username', 'mobile as phone', 'status', 'password', 'insert_time', 'update_time']);
  146. // 用户不存在
  147. if (!$admin) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  148. // 用户不存在
  149. if ($admin['status']) return json_send(['code' => 'error', 'msg' => '该账号已停用']);
  150. // 转数组
  151. $admin = $admin->toArray();
  152. // 比对密码
  153. if (md5($password) != $admin['password']) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  154. // 登录
  155. $accessToken = $EmployeeModel->Login($admin['uid'], $admin['company_id'], 'manager');
  156. // 比对密码
  157. if (isset($accessToken['error'])) return json_send(['code' => 'error', 'msg' => '登录失败', 'data' => $accessToken['data']]);
  158. // 获取权限列表
  159. $accessToken['username'] = $admin['username'];
  160. $accessToken['is_system_admin'] = 0;
  161. // 表单令牌
  162. return json_send(['code' => 'success', 'msg' => '登录成功', 'data' => $accessToken]);
  163. }
  164. /**
  165. * 发送验证码
  166. * @author 唐远望
  167. * @version 1.0
  168. * @date 2026-01-15
  169. * @param string phone 手机号码
  170. *
  171. */
  172. public function send_code(Request $Request, EmployeeModel $EmployeeModel)
  173. {
  174. // 验证规则
  175. $Request->scene('send_code')->validate();
  176. // 接收数据
  177. $mobile = request('phone', '');
  178. if (!$mobile) return json_send(['code' => 'error', 'msg' => '请先填写手机号']);
  179. // 获取数据
  180. $session = Cache::get('loginSmsCode_' . $mobile);
  181. // 如果有数据,并且验证码创建的时间在一分钟之内
  182. if ($session && time() - $session['create_time'] < 60) return json_send(['code' => 'error', 'msg' => '请稍后再试']);
  183. // 查询用户
  184. $admin = $EmployeeModel->query()->where('mobile', $mobile)->first(['status']);
  185. if ($admin && $admin['status']) return json_send(['code' => 'error', 'msg' => '用户已被停用']);
  186. $code = strval(rand(100000, 999999));
  187. $result = Sms::sendCode($mobile, $code);
  188. if (isset($result['error'])) return json_send(['code' => 'error', 'msg' => $result['error']]);
  189. $session = ['code' => $code, 'mobile' => $mobile, 'create_time' => time()];
  190. Cache::put('loginSmsCode_' . $mobile, $session, 120);
  191. return json_send(['code' => 'success', 'msg' => '发送成功', 'data' => '']);
  192. }
  193. /**
  194. * 邮箱登录 /manager/login/email
  195. * @author 唐远望
  196. * @version 1.0
  197. * @date 2025-12-04
  198. * @param string email 邮箱号码
  199. * @param string password 登录密码
  200. *
  201. */
  202. public function email(Request $Request, AuthRule $AuthRule, EmployeeModel $EmployeeModel)
  203. {
  204. // 验证规则
  205. $Request->scene('email')->validate();
  206. // 接收数据
  207. $email = $Request->input('email', '');
  208. // 接收数据
  209. $password = $Request->input('password', '');
  210. // 查询用户
  211. $admin = $EmployeeModel->where('email', $email)->first(['company_id', 'id as uid', 'name as username', 'mobile as phone', 'status', 'password', 'insert_time', 'update_time']);
  212. // 用户不存在
  213. if (!$admin) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  214. // 用户不存在
  215. if ($admin['status']) return json_send(['code' => 'error', 'msg' => '该账号已停用']);
  216. // 转数组
  217. $admin = $admin->toArray();
  218. // 比对密码
  219. if (md5($password) != $admin['password']) return json_send(['code' => 'error', 'msg' => '密码错误或账号不存在']);
  220. // 登录
  221. $accessToken = $EmployeeModel->Login($admin['uid'], $admin['company_id'], 'manager');
  222. // 比对密码
  223. if (isset($accessToken['error'])) return json_send(['code' => 'error', 'msg' => '登录失败', 'data' => $accessToken['data']]);
  224. // 获取权限列表
  225. $accessToken['username'] = $admin['username'];
  226. $accessToken['is_system_admin'] = 0;
  227. // 表单令牌
  228. return json_send(['code' => 'success', 'msg' => '登录成功', 'data' => $accessToken]);
  229. }
  230. /**
  231. * 手机验证码登录 /manager/login/mobile_code
  232. * @author 唐远望
  233. * @version 1.0
  234. * @date 2026-01-15
  235. * @param string mobile 手机号码
  236. * @param string code 验证码
  237. *
  238. */
  239. public function mobile_code(Request $Request, AuthRule $AuthRule, EmployeeModel $EmployeeModel)
  240. {
  241. // 验证规则
  242. $Request->scene('mobile_code')->validate();
  243. // 接收数据
  244. $phone = $Request->input('phone', '');
  245. // 接收数据
  246. $code = $Request->input('code', '');
  247. // 获取数据
  248. $session = Cache::get('loginSmsCode_' . $phone);
  249. if (!$session) return json_send(['code' => 'error', 'msg' => '请先获取手机号验证码']);
  250. if ($session['code'] != $code || $session['mobile'] != $phone) return json_send(['code' => 'error', 'msg' => '验证码错误']);
  251. // 查询用户
  252. $admin = $EmployeeModel->where('mobile', $phone)->first(['company_id', 'id as uid', 'name as username', 'mobile as phone', 'status', 'password', 'insert_time', 'update_time']);
  253. // 用户不存在
  254. if (!$admin) return json_send(['code' => 'error', 'msg' => '账号不存在']);
  255. // 用户不存在
  256. if ($admin['status']) return json_send(['code' => 'error', 'msg' => '该账号已停用']);
  257. // 转数组
  258. $admin = $admin->toArray();
  259. // 登录
  260. $accessToken = $EmployeeModel->Login($admin['uid'], $admin['company_id'], 'manager');
  261. // 比对密码
  262. if (isset($accessToken['error'])) return json_send(['code' => 'error', 'msg' => '登录失败', 'data' => $accessToken['data']]);
  263. // 获取权限列表
  264. $accessToken['username'] = $admin['username'];
  265. $accessToken['is_system_admin'] = 0;
  266. // 表单令牌
  267. return json_send(['code' => 'success', 'msg' => '登录成功', 'data' => $accessToken]);
  268. }
  269. /**
  270. * 微信扫码登录 /manager/login/wechat
  271. * @author 唐远望
  272. * @version 1.0
  273. * @date 2026-01-19
  274. * @param string open_code 微信扫码登录的code
  275. *
  276. */
  277. public function wechat(Request $Request, AuthRule $AuthRule, EmployeeModel $EmployeeModel, EmployeeOpenidModel $EmployeeOpenidModel)
  278. {
  279. // 验证规则
  280. $Request->scene('wechat')->validate();
  281. // 接收数据
  282. $open_code = $Request->input('open_code', '');
  283. $wechatApp = new WeChatWebApp();
  284. $tokenData = $wechatApp->getAccessTokenByCode($open_code);
  285. if (!$tokenData) return json_send(['code' => 'error', 'msg' => '获取微信用户信息失败']);
  286. $user_open_data = $EmployeeOpenidModel->where(['openid' => $tokenData['openid']])->first();
  287. if (!$user_open_data) return json_send(['code' => 'error', 'msg' => '未绑定账号']);
  288. // 查询用户
  289. $admin = $EmployeeModel->where('id', $user_open_data->employee_id)->first(['company_id', 'id as uid', 'name as username', 'mobile as phone', 'status', 'password', 'insert_time', 'update_time']);
  290. // 用户不存在
  291. if (!$admin) return json_send(['code' => 'error', 'msg' => '账号不存在']);
  292. // 用户不存在
  293. if ($admin['status']) return json_send(['code' => 'error', 'msg' => '该账号已停用']);
  294. // 转数组
  295. $admin = $admin->toArray();
  296. // 登录
  297. $accessToken = $EmployeeModel->Login($admin['uid'], $admin['company_id'], 'manager');
  298. // 比对密码
  299. if (isset($accessToken['error'])) return json_send(['code' => 'error', 'msg' => '登录失败', 'data' => $accessToken['data']]);
  300. // 获取权限列表
  301. $accessToken['username'] = $admin['username'];
  302. $accessToken['is_system_admin'] = 0;
  303. // 表单令牌
  304. return json_send(['code' => 'success', 'msg' => '登录成功', 'data' => $accessToken]);
  305. }
  306. /**
  307. * 微信扫码授权绑定 /manager/login/wechat_bind
  308. * @author 唐远望
  309. * @version 1.0
  310. * @date 2026-01-19
  311. * @param string open_code 微信扫码登录的code
  312. *
  313. */
  314. public function wechat_bind(Request $Request, EmployeeModel $EmployeeModel, EmployeeOpenidModel $EmployeeOpenidModel)
  315. {
  316. // 验证规则
  317. $Request->scene('wechat_bind')->validate();
  318. $uid = request('access_token.uid', 0);
  319. $company_id = request('access_token.company_id', '0');
  320. // 接收数据
  321. $open_code = $Request->input('open_code', '');
  322. $wechatApp = new WeChatWebApp();
  323. $tokenData = $wechatApp->getAccessTokenByCode($open_code);
  324. if (!$tokenData) return json_send(['code' => 'error', 'msg' => '获取微信用户信息失败']);
  325. // $user_open_data = $EmployeeOpenidModel->where(['openid' => $tokenData['openid']])->first();
  326. // if ($user_open_data) return json_send(['code' => 'error', 'msg' => '微信已绑定,无需重复绑定']);
  327. //新增绑定记录
  328. $user_info = $EmployeeModel->where(['id' => $uid])->first();
  329. if (!$user_info) return json_send(['code' => 'error', 'msg' => '未找到用户信息']);
  330. //查询openid是否绑定其它用户
  331. $openid_user_info = $EmployeeOpenidModel->where(['openid' => $tokenData['openid']])->first();
  332. if ($openid_user_info && $openid_user_info->employee_id != $uid) {
  333. return json_send(['code' => 'error', 'msg' => '该微信已绑定其它账号']);
  334. }
  335. DB::beginTransaction();
  336. try {
  337. $user_info->band_wechat = 1; //绑定微信0=未绑定1=已绑定
  338. $user_info->save();
  339. //查询是否存在绑定记录
  340. $band_wechat_data = $EmployeeOpenidModel->where(['employee_id' => $uid])->first();
  341. if (!$band_wechat_data) {
  342. //查询关注公众号记录
  343. $unionid = $tokenData['unionid'] ?? '';
  344. $official_user_info = $EmployeeOpenidModel->where(['unionid' => $unionid])->first();
  345. if ($official_user_info) {
  346. $official_user_info->company_id = $company_id;
  347. $official_user_info->employee_id = $uid;
  348. $official_user_info->openid = $tokenData['openid'];
  349. $official_user_info->update_time = time();
  350. $official_user_info->save();
  351. } else {
  352. $EmployeeOpenidModel->insertGetId([
  353. 'company_id' => $company_id,
  354. 'employee_id' => $uid,
  355. 'unionid' => $tokenData['unionid'] ?? '',
  356. 'openid' => $tokenData['openid'],
  357. 'insert_time' => time()
  358. ]);
  359. }
  360. } else {
  361. $band_wechat_data->unionid = $tokenData['unionid'] ?? '';
  362. $band_wechat_data->openid = $tokenData['openid'];
  363. $band_wechat_data->update_time = time();
  364. $band_wechat_data->save();
  365. }
  366. DB::commit();
  367. return json_send(['code' => 'success', 'msg' => '绑定成功', 'data' => '']);
  368. } catch (\Exception $e) {
  369. DB::rollBack();
  370. return json_send(['code' => 'error', 'msg' => '绑定失败', 'data' => $e->getMessage()]);
  371. }
  372. }
  373. }