fix: 调整路由顺序,修复静态文件被JWT拦截的问题

- 将 /static/{tail:.*} 路由移到受保护 scope 之前
- 确保静态文件无需认证即可访问
This commit is contained in:
2026-04-15 11:51:59 +08:00
parent 913a235e5c
commit a819a0db91
9 changed files with 728 additions and 678 deletions

118
src/handlers/admin.rs Normal file
View File

@@ -0,0 +1,118 @@
use actix_web::{web, get, put, HttpResponse, Responder};
use sqlx::postgres::PgPool;
use tracing::error;
use chrono::{DateTime, Utc};
use crate::db;
use crate::models::{Claims, ErrorResponse, UpdatePaymentRequest};
#[get("/api/admin/users/{id}")]
pub async fn admin_get_user(
path: web::Path<i32>,
pool: web::Data<PgPool>,
claims: web::ReqData<Claims>,
) -> impl Responder {
let target_user_id = path.into_inner();
tracing::info!("管理员获取用户信息, 目标用户ID: {}", target_user_id);
// 验证当前用户是否为管理员
let current_user = match db::get_user_by_id(pool.get_ref(), claims.user_id).await {
Ok(user) => user,
Err(e) => {
error!("获取当前用户信息失败: {}", e);
return HttpResponse::Ok().json(serde_json::json!({
"success": false,
"errcode": 500,
"errmsg": "获取用户信息失败"
}));
}
};
if !current_user.is_admin {
return HttpResponse::Forbidden().json(serde_json::json!({
"success": false,
"errcode": 403,
"errmsg": "无权限执行此操作"
}));
}
// 获取目标用户信息
match db::get_user_by_id(pool.get_ref(), target_user_id).await {
Ok(user) => HttpResponse::Ok().json(serde_json::json!({
"success": true,
"data": user
})),
Err(e) => {
error!("获取目标用户信息失败: {}", e);
let errcode = if e.starts_with("未找到") { 404 } else { 500 };
HttpResponse::Ok().json(serde_json::json!({
"success": false,
"errcode": errcode,
"errmsg": e
}))
}
}
}
#[put("/api/admin/users/{id}/payment")]
pub async fn admin_update_user_payment(
path: web::Path<i32>,
pool: web::Data<PgPool>,
claims: web::ReqData<Claims>,
body: web::Json<UpdatePaymentRequest>,
) -> impl Responder {
let target_user_id = path.into_inner();
tracing::info!("管理员更新用户付费状态, 目标用户ID: {}", target_user_id);
// 验证当前用户是否为管理员
let current_user = match db::get_user_by_id(pool.get_ref(), claims.user_id).await {
Ok(user) => user,
Err(e) => {
error!("获取当前用户信息失败: {}", e);
return HttpResponse::Ok().json(serde_json::json!({
"success": false,
"errcode": 500,
"errmsg": "获取用户信息失败"
}));
}
};
if !current_user.is_admin {
return HttpResponse::Forbidden().json(serde_json::json!({
"success": false,
"errcode": 403,
"errmsg": "无权限执行此操作"
}));
}
// 解析 paid_expires_at
let paid_expires_at = match &body.paid_expires_at {
Some(date_str) => match DateTime::parse_from_rfc3339(date_str) {
Ok(dt) => Some(dt.with_timezone(&Utc)),
Err(e) => {
return HttpResponse::BadRequest().json(serde_json::json!({
"success": false,
"errcode": 400,
"errmsg": format!("日期格式错误: {}", e)
}));
}
},
None => None,
};
// 更新用户付费状态
match db::update_user_payment_status(pool.get_ref(), target_user_id, body.is_paid, paid_expires_at).await {
Ok(_) => HttpResponse::Ok().json(serde_json::json!({
"success": true,
"message": "用户付费状态已更新"
})),
Err(e) => {
error!("更新用户付费状态失败: {}", e);
HttpResponse::Ok().json(serde_json::json!({
"success": false,
"errcode": 500,
"errmsg": e
}))
}
}
}