From bd60a72e6849b759a64ec3aa7a645ab6a89b61c5 Mon Sep 17 00:00:00 2001 From: Milky0217 Date: Fri, 17 Oct 2025 19:39:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86convertedwindspeed?= =?UTF-8?q?=E4=B8=BAfloat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main.rs | 50 +++++++++++++++----------------------------- src/models.rs | 3 +-- templates/index.html | 4 ++-- 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/src/main.rs b/src/main.rs index d694843..99472f0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -144,46 +144,30 @@ async fn login( } }; - // 检查用户是否已存在,不存在则创建 - let query = r#" - INSERT INTO users (openid, name, type) - VALUES ($1, left($1, 8), 2) - ON CONFLICT (openid) DO NOTHING - RETURNING id -"#; + // 【核心修改】使用标准的 UPSERT 语法,原子性地创建或获取用户 + let upsert_query = r#" + INSERT INTO users (openid, name, type) + VALUES ($1, left($1, 8), 2) + ON CONFLICT (openid) DO UPDATE SET + -- 这里可以更新一些需要变更的字段,例如最后登录时间 + -- 如果没有需要更新的,可以使用一个技巧来确保 RETURNING 总是有效 + id = users.id + RETURNING id + "#; - let user_id = match sqlx::query_as::<_, (i32,)>(query) + // 使用 fetch_one,因为我们确定这个查询总能返回一个 id + let user_id = match sqlx::query_as::<_, (i32,)>(upsert_query) .bind(&openid) - .fetch_optional(pool.get_ref()) + .fetch_one(pool.get_ref()) // <--- 注意这里是 fetch_one .await { - Ok(Some((id,))) => { - info!("用户已存在,用户ID: {}", id); + Ok((id,)) => { + // 无论是新用户还是老用户,都成功获取了 ID + info!("用户登录/注册成功,用户ID: {}", id); id } - Ok(None) => { - // 新用户创建成功,查询ID - match sqlx::query_as::<_, (i32,)>("SELECT id FROM users WHERE openid = $1") - .bind(&openid) - .fetch_one(pool.get_ref()) - .await - { - Ok((id,)) => { - info!("新用户创建成功,用户ID: {}", id); - id - } - Err(e) => { - error!("新用户创建后查询ID失败: {}", e); - return HttpResponse::InternalServerError().json(ErrorResponse { - error: "创建用户后查询ID失败".to_string(), - errcode: Some(500), - errmsg: Some(e.to_string()), - }); - } - } - } Err(e) => { - error!("用户查询/创建失败: {}", e); + error!("用户信息处理失败: {}", e); return HttpResponse::InternalServerError().json(ErrorResponse { error: "用户信息处理失败".to_string(), errcode: Some(500), diff --git a/src/models.rs b/src/models.rs index 807928c..2fbf47a 100644 --- a/src/models.rs +++ b/src/models.rs @@ -169,10 +169,9 @@ pub struct WeatherData { // --- 以下是修改的重点 --- // 这些字段在前端是条件性发送的,因此在 Rust 中也必须是可选的 - #[serde(rename = "convertedWindSpeed")] #[sqlx(rename = "convertedwindspeed")] - pub converted_wind_speed: Option, // <-- 修改: i32 -> Option + pub converted_wind_speed: Option, pub date: NaiveDate, diff --git a/templates/index.html b/templates/index.html index c177747..126934f 100644 --- a/templates/index.html +++ b/templates/index.html @@ -53,11 +53,11 @@

太阳倾角计算公式:▶