使用了logger来进行后端的消息记录

This commit is contained in:
2025-09-30 15:59:15 +08:00
parent 9880124c87
commit 7fa1ae6301
6 changed files with 353 additions and 26 deletions

View File

@@ -1,6 +1,7 @@
use actix_web::middleware::from_fn;
use actix_web::{App, HttpResponse, HttpServer, Responder, delete, get, post, web};
use include_dir::{Dir, include_dir};
use log::{debug, error, info, warn};
use reqwest::Client;
use sqlx::postgres::PgPool;
mod auth;
@@ -11,13 +12,12 @@ use auth::{generate_token, jwt_middleware};
use db::{create_pool, insert_weather_data};
use models::{ErrorResponse, WeChatApiResponse, WeChatLoginRequest, WeatherData};
use crate::models::Claims;
use crate::models::{Claims, TokenResponse};
// 编译时嵌入整个 static 目录
static STATIC_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/static");
static TEMPLATES_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/templates");
// 登录的API端点
#[post("/api/login")]
async fn login(
pool: web::Data<PgPool>,
@@ -26,8 +26,12 @@ async fn login(
) -> impl Responder {
// 从环境变量获取微信小程序配置
let appid = match std::env::var("WECHAT_APPID") {
Ok(id) => id,
Ok(id) => {
debug!("成功加载微信小程序appid");
id
}
Err(_) => {
error!("环境变量中未配置WECHAT_APPID");
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "服务器配置错误缺少微信小程序appid".to_string(),
errcode: None,
@@ -37,8 +41,12 @@ async fn login(
};
let secret = match std::env::var("WECHAT_SECRET") {
Ok(secret) => secret,
Ok(secret) => {
debug!("成功加载微信小程序secret");
secret
}
Err(_) => {
error!("环境变量中未配置WECHAT_SECRET");
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "服务器配置错误缺少微信小程序secret".to_string(),
errcode: None,
@@ -52,12 +60,16 @@ async fn login(
"https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code",
appid, secret, req.code
);
debug!("准备调用微信API: {}", url.replace(&secret, "***")); // 日志中隐藏secret
// 调用微信API
let wechat_response = match http_client.get(&url).send().await {
Ok(response) => response,
Ok(response) => {
debug!("微信API请求成功状态码: {}", response.status());
response
}
Err(e) => {
eprintln!("请求微信API失败: {}", e);
error!("微信API请求失败: {}", e);
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "请求微信服务失败".to_string(),
errcode: None,
@@ -68,9 +80,12 @@ async fn login(
// 解析微信API响应
let wechat_data: WeChatApiResponse = match wechat_response.json().await {
Ok(data) => data,
Ok(data) => {
debug!("微信API响应解析成功");
data
}
Err(e) => {
eprintln!("解析微信API响应失败: {}", e);
error!("微信API响应解析失败: {}", e);
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "解析微信响应失败".to_string(),
errcode: None,
@@ -81,6 +96,10 @@ async fn login(
// 检查微信API响应中的错误
if let Some(errcode) = wechat_data.errcode {
warn!(
"微信登录验证失败 - 错误码: {}, 错误信息: {:?}",
errcode, wechat_data.errmsg
);
return HttpResponse::BadRequest().json(ErrorResponse {
error: "微信登录失败".to_string(),
errcode: Some(errcode),
@@ -90,8 +109,14 @@ async fn login(
// 获取openid
let openid = match wechat_data.openid {
Some(id) => id,
Some(id) => {
// 日志中只显示openid的前4位和后4位保护用户隐私
let masked_openid = format!("{}***{}", &id[0..4], &id[id.len() - 4..]);
debug!("获取到用户openid: {}", masked_openid);
id
}
None => {
error!("微信API响应中未包含openid");
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "微信API未返回openid".to_string(),
errcode: None,
@@ -100,7 +125,7 @@ async fn login(
}
};
// 3. 检查用户是否已存在,不存在则创建(显式处理数据库错误)
// 检查用户是否已存在,不存在则创建
let query = r#"
INSERT INTO users (openid, name, type)
VALUES ($1, left($1, 8), 2)
@@ -114,21 +139,22 @@ async fn login(
.await
{
Ok(Some((id,))) => {
// 已存在用户直接获取ID
println!("用户已存在ID: {}", id);
info!("用户已存在用户ID: {}", id);
id
}
Ok(None) => {
// 新用户创建成功,需再次查询ID因ON CONFLICT DO NOTHING不返回值
println!("新用户已创建openid: {}", openid);
// 新用户创建成功查询ID
match sqlx::query_as::<_, (i32,)>("SELECT id FROM users WHERE openid = $1")
.bind(&openid)
.fetch_one(pool.get_ref())
.await
{
Ok((id,)) => id,
Ok((id,)) => {
info!("新用户创建成功用户ID: {}", id);
id
}
Err(e) => {
eprintln!("查询新用户ID失败: {}", e);
error!("新用户创建后查询ID失败: {}", e);
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "创建用户后查询ID失败".to_string(),
errcode: Some(500),
@@ -138,8 +164,7 @@ async fn login(
}
}
Err(e) => {
// 数据库操作失败
eprintln!("用户查询/创建失败: {}", e);
error!("用户查询/创建失败: {}", e);
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "用户信息处理失败".to_string(),
errcode: Some(500),
@@ -148,11 +173,11 @@ async fn login(
}
};
// 4. 生成JWT token(显式处理所有可能的错误)
// 4.1 获取JWT密钥
// 生成JWT token
let jwt_secret = match std::env::var("JWT_SECRET") {
Ok(secret) => secret,
Err(_) => {
error!("环境变量中未配置JWT_SECRET");
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "服务器配置错误缺少JWT_SECRET".to_string(),
errcode: Some(500),
@@ -161,11 +186,26 @@ async fn login(
}
};
// 4.2 编码生成token
let token = generate_token(user_id, &openid, 2, &jwt_secret);
// 生成token
let token = match generate_token(user_id, &openid, 2, &jwt_secret) {
Ok(t) => {
// 日志中只显示token的前8位保护安全
debug!("JWT生成成功: {}", &t[0..8]);
t
}
Err(e) => {
error!("JWT生成失败: {}", e);
return HttpResponse::InternalServerError().json(ErrorResponse {
error: "生成身份令牌失败".to_string(),
errcode: Some(500),
errmsg: Some(e.to_string()),
});
}
};
// 5. 返回成功响应包含token
HttpResponse::Ok().json(token)
info!("用户登录成功用户ID: {}", user_id);
let token_response = TokenResponse::new(token);
HttpResponse::Ok().json(token_response)
}
#[post("/api/post-weather-data")]
@@ -566,6 +606,16 @@ fn create_server_config(
#[actix_web::main]
async fn main() -> std::io::Result<()> {
if let Err(e) = dotenvy::dotenv() {
eprintln!("警告:加载.env文件失败使用系统环境变量: {}", e);
}
// 2. 打印当前 RUST_LOG 的值(关键:验证配置是否生效)
let rust_log = std::env::var("RUST_LOG").unwrap_or_else(|_| "未设置".to_string());
eprintln!("当前 RUST_LOG 级别:{}", rust_log); // 这行用 eprintln!,不受日志级别影响
env_logger::init(); // 添加这一行
info!("logger init successful");
// 初始化数据库连接池
let pool = match create_pool().await {
Ok(pool) => pool,