243 lines
7.2 KiB
PHP
243 lines
7.2 KiB
PHP
<?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
|
||
]);
|
||
}
|
||
}
|