feat(api): 初始化笔记应用后端基础架构
- 添加环境配置文件 .env.example 包含数据库、JWT、CORS等配置 - 创建 .gitignore 文件忽略敏感文件和临时文件 - 配置 Apache 重写规则支持路由转发 - 实现 JWT 认证中间件提供用户身份验证功能 - 添加 MySQL 数据库初始化脚本包含分组、图片、笔记表结构
This commit is contained in:
137
biji-php/src/Controllers/UserController.php
Normal file
137
biji-php/src/Controllers/UserController.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use App\Models\User;
|
||||
use App\Models\SystemSetting;
|
||||
use App\Models\RegistrationCode;
|
||||
use App\Utils\JWTUtil;
|
||||
use App\Utils\Response as ApiResponse;
|
||||
|
||||
class UserController
|
||||
{
|
||||
public function register(Request $request, Response $response)
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
$username = $data['username'] ?? '';
|
||||
$password = $data['password'] ?? '';
|
||||
$email = $data['email'] ?? '';
|
||||
$registrationCode = $data['registrationCode'] ?? '';
|
||||
|
||||
// 验证输入
|
||||
if (empty($username) || empty($password) || empty($email)) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('用户名、密码和邮箱不能为空')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(400);
|
||||
}
|
||||
|
||||
// 检查注册功能是否开启
|
||||
$systemSetting = new SystemSetting();
|
||||
if (!$systemSetting->isRegistrationEnabled()) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('注册功能已关闭')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(403);
|
||||
}
|
||||
|
||||
// 验证注册码
|
||||
$regCodeModel = new RegistrationCode();
|
||||
if (!$regCodeModel->validateCode($registrationCode)) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('无效或已过期的注册码')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(400);
|
||||
}
|
||||
|
||||
$userModel = new User();
|
||||
|
||||
// 检查用户名是否已存在
|
||||
if ($userModel->findByUsername($username)) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('用户名已存在')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(400);
|
||||
}
|
||||
|
||||
try {
|
||||
$userId = $userModel->create($username, $password, $email);
|
||||
$user = $userModel->findById($userId);
|
||||
unset($user['password']); // 不返回密码
|
||||
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::success($user, '注册成功')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
} catch (\Exception $e) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::error('注册失败: ' . $e->getMessage())));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(500);
|
||||
}
|
||||
}
|
||||
|
||||
public function login(Request $request, Response $response)
|
||||
{
|
||||
$data = $request->getParsedBody();
|
||||
$username = $data['username'] ?? '';
|
||||
$password = $data['password'] ?? '';
|
||||
|
||||
if (empty($username) || empty($password)) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('用户名和密码不能为空')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(400);
|
||||
}
|
||||
|
||||
$userModel = new User();
|
||||
$user = $userModel->findByUsername($username);
|
||||
|
||||
if (!$user || !$userModel->verifyPassword($password, $user['password'])) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('用户名或密码错误')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(401);
|
||||
}
|
||||
|
||||
// 生成 JWT token
|
||||
$token = JWTUtil::encode($user['id'], $user['username']);
|
||||
$expireTime = date('Y-m-d H:i:s', time() + ($_ENV['JWT_EXPIRE'] ?? 86400));
|
||||
|
||||
// 更新数据库中的 token
|
||||
$userModel->updateToken($user['id'], $token, $expireTime);
|
||||
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::success(['token' => $token], '登录成功')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
|
||||
public function validateToken(Request $request, Response $response)
|
||||
{
|
||||
// 如果能到达这里,说明 token 已经通过中间件验证
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::success(null, 'Token is valid')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
|
||||
public function updatePassword(Request $request, Response $response)
|
||||
{
|
||||
$userId = $request->getAttribute('userId');
|
||||
$data = $request->getParsedBody();
|
||||
$oldPassword = $data['oldPassword'] ?? '';
|
||||
$newPassword = $data['newPassword'] ?? '';
|
||||
|
||||
if (empty($oldPassword) || empty($newPassword)) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('旧密码和新密码不能为空')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(400);
|
||||
}
|
||||
|
||||
$userModel = new User();
|
||||
$user = $userModel->findById($userId);
|
||||
|
||||
if (!$userModel->verifyPassword($oldPassword, $user['password'])) {
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::fail('旧密码错误')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8')->withStatus(400);
|
||||
}
|
||||
|
||||
$userModel->updatePassword($userId, $newPassword);
|
||||
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::success(null, '密码更新成功')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
|
||||
public function deleteUser(Request $request, Response $response)
|
||||
{
|
||||
$userId = $request->getAttribute('userId');
|
||||
|
||||
$userModel = new User();
|
||||
$userModel->delete($userId);
|
||||
|
||||
$response->getBody()->write(ApiResponse::json(ApiResponse::success(null, '用户删除成功')));
|
||||
return $response->withHeader('Content-Type', 'application/json; charset=utf-8');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user