tp/app/admin/controller/LoginController.php
2026-02-24 10:12:05 +08:00

243 lines
7.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
namespace app\admin\controller;
use app\admin\BaseController;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Cache;
use think\response\Json;
use app\service\JwtService;
use app\model\AdminUser;
use app\model\System\SystemSiteSettings;
class LoginController extends BaseController
{
private function generateToken($userInfo): string
{
return JwtService::generateToken($userInfo);
}
private function verifyToken($token): ?array
{
return JwtService::verifyToken($token);
}
/**
* 登录接口
* @return Json
*/
public function login(): Json
{
try {
$data = $this->request->param();
if (isset($data['email'])) {
$data['account'] = $data['email'];
} elseif (isset($data['phone'])) {
$data['account'] = $data['phone'];
}
try {
$this->validate($data, [
'account|账号' => 'require|length:3,32',
'password|密码' => 'require|length:6,32'
]);
} catch (ValidateException $e) {
$this->logFail('登录管理', '登录', $e->getMessage());
return json([
'code' => 400,
'msg' => $e->getError()
]);
}
$user = AdminUser::where('account', $data['account'])
->where('status', 1)
->where('delete_time', null)
->find();
if (!$user) {
return json([
'code' => 401,
'msg' => '账号不存在或已禁用'
]);
}
if (md5($data['password']) !== $user['password']) {
return json([
'code' => 401,
'msg' => '密码错误'
]);
}
// 更新登录次数和IP确保 login_count 不为 null
try {
$loginCount = isset($user['login_count']) && $user['login_count'] !== null ? (int)$user['login_count'] : 0;
AdminUser::where('id', $user['id'])->update([
'login_count' => $loginCount + 1,
'last_login_ip' => $this->request->ip()
]);
} catch (\Exception $e) {
// 更新登录信息失败不影响登录流程
error_log('更新登录信息失败: ' . $e->getMessage());
}
$userInfo = [
'id' => $user['id'],
'account' => $user['account'],
'name' => $user['name'],
'group_id' => $user['group_id']
];
try {
$token = $this->generateToken($userInfo);
} catch (\Exception $e) {
$this->logFail('登录管理', '登录', 'Token生成失败: ' . $e->getMessage());
return json([
'code' => 500,
'msg' => '登录失败,请稍后重试'
]);
}
// 记录日志,但不影响登录流程
try {
$this->logSuccess('登录管理', '登录', ['id' => $user['id']], $userInfo);
} catch (\Exception $e) {
// 日志记录失败不影响登录
error_log('登录日志记录失败: ' . $e->getMessage());
}
return json([
'code' => 200,
'msg' => '登录成功',
'data' => [
'token' => $token,
'user' => $userInfo
]
]);
} catch (\Exception $e) {
// 捕获所有未预期的错误
error_log('登录失败: ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine());
try {
$this->logFail('登录管理', '登录', $e->getMessage());
} catch (\Exception $logError) {
error_log('记录登录失败日志也失败: ' . $logError->getMessage());
}
return json([
'code' => 500,
'msg' => '登录失败,请稍后重试'
]);
}
}
/**
* 退出登录
* @return Json
*/
public function logout(): Json
{
$authHeader = $this->request->header('Authorization', '');
$userInfo = null;
if (preg_match('/Bearer\s+(.+)/i', $authHeader, $matches)) {
$tokenData = $this->verifyToken($matches[1]);
if ($tokenData && isset($tokenData['user'])) {
$userInfo = (array)$tokenData['user'];
}
}
if ($userInfo && isset($userInfo['id'])) {
$this->logSuccess('登录管理', '退出登录', ['result' => 'success'], $userInfo);
} else {
\app\model\OperationLog::create([
'user_id' => 0,
'user_account' => '',
'user_name' => '未知用户',
'module' => '登录管理',
'action' => '退出登录',
'method' => 'POST',
'url' => $this->request->url(true),
'ip' => $this->request->ip(),
'user_agent' => $this->request->header('user-agent', ''),
'request_data' => null,
'response_data' => json_encode(['result' => 'success'], JSON_UNESCAPED_UNICODE),
'status' => 1,
'error_message' => '',
'execution_time' => 0.0,
]);
}
return json([
'code' => 200,
'msg' => '退出成功'
]);
}
/**
* 获取当前登录用户信息
* @return Json
*/
public function userInfo(): Json
{
$authHeader = $this->request->header('Authorization', '');
if (!preg_match('/Bearer\s+(.+)/i', $authHeader, $matches)) {
return json([
'code' => 401,
'msg' => '未登录'
]);
}
$tokenData = $this->verifyToken($matches[1]);
if (!$tokenData || !isset($tokenData['user'])) {
return json([
'code' => 401,
'msg' => 'Token无效'
]);
}
$user = (array)$tokenData['user'];
$user_id = $user['id'];
$userData = AdminUser::where('id', $user_id)
->where('delete_time', null)
->field('id, account, name, phone, qq, sex, group_id, status, create_time, update_time')
->find();
if (!$userData) {
return json([
'code' => 404,
'msg' => '用户不存在'
]);
}
return json([
'code' => 200,
'msg' => '获取成功',
'data' => $userData->toArray()
]);
}
public function getAdminUserFromToken(): array
{
return JwtService::getUserFromHeader($this->request->header('Authorization', ''));
}
public function loginInfo()
{
$loginInfo = SystemSiteSettings::select();
return json([
'code' => 200,
'msg' => '获取成功',
'data' => $loginInfo
]);
}
}