将insert_weather_data方法移到db.rs
This commit is contained in:
105
src/db.rs
105
src/db.rs
@@ -1,10 +1,105 @@
|
|||||||
use sqlx::postgres::PgPool; // 修改导入路径
|
use sqlx::PgPool;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
// 从 models 模块引入 WeatherData 结构体
|
||||||
|
use crate::models::WeatherData;
|
||||||
|
|
||||||
|
// 这个函数封装了所有与数据库交互的逻辑
|
||||||
|
pub async fn insert_weather_data(pool: &PgPool, weather_data: &WeatherData) -> Result<i32, String> {
|
||||||
|
// 1. 根据 openid 查询 user_id
|
||||||
|
let user_id = match sqlx::query_as::<_, (i32,)>("SELECT id FROM users WHERE openid = $1")
|
||||||
|
.bind(&weather_data.openid)
|
||||||
|
.fetch_optional(pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(Some((id,))) => id,
|
||||||
|
Ok(None) => {
|
||||||
|
return Err(format!("未找到openid为 {} 的用户", weather_data.openid));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
return Err(format!("查询用户失败: {}", e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. 准备插入数据的 SQL 语句
|
||||||
|
let insert_query = r#"
|
||||||
|
INSERT INTO weather_data (
|
||||||
|
user_id, title, date, hour, min, longitude, latitude, daysincejanfirst,
|
||||||
|
theta, solardeclination, sunaltitude, overallcloudiness, lowcloudiness,
|
||||||
|
cloudindex, solarradiationlevel, hasmeasuredwindspeed, measuredwindspeed,
|
||||||
|
convertedwindspeed, measurementheight, areatype, pointwindspeed,
|
||||||
|
atmosphericstability, suitabilitydegree, winddirection, averagewinddirection,
|
||||||
|
winddirectionstandarddeviation, windspeed, averagewindspeed, windspeedsuitability,
|
||||||
|
winddirectionsuitability, overallsuitability, inspectiontype, assignmentnumber,
|
||||||
|
calculatedwindspeed
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19,
|
||||||
|
$20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34
|
||||||
|
) RETURNING id
|
||||||
|
"#;
|
||||||
|
|
||||||
|
// 转换经纬度为字符串
|
||||||
|
let longitude_str = weather_data.longitude.to_string();
|
||||||
|
let latitude_str = weather_data.latitude.to_string();
|
||||||
|
|
||||||
|
// 3. 执行插入操作
|
||||||
|
let inserted_id = match sqlx::query_as::<_, (i32,)>(insert_query)
|
||||||
|
.bind(user_id)
|
||||||
|
.bind(&weather_data.title)
|
||||||
|
.bind(weather_data.date) // NaiveDate 类型,sqlx 会自动处理
|
||||||
|
.bind(weather_data.hours)
|
||||||
|
.bind(weather_data.min)
|
||||||
|
.bind(&longitude_str)
|
||||||
|
.bind(&latitude_str)
|
||||||
|
.bind(weather_data.day_since_jan_first)
|
||||||
|
.bind(weather_data.theta)
|
||||||
|
.bind(weather_data.solar_declination)
|
||||||
|
.bind(weather_data.sun_altitude)
|
||||||
|
.bind(&weather_data.overall_cloudiness)
|
||||||
|
.bind(&weather_data.low_cloudiness)
|
||||||
|
.bind(&weather_data.cloud_index)
|
||||||
|
.bind(weather_data.solar_radiation_level as i32)
|
||||||
|
.bind(weather_data.has_measured_wind_speed)
|
||||||
|
.bind(weather_data.measured_wind_speed)
|
||||||
|
.bind(weather_data.converted_wind_speed as i32)
|
||||||
|
.bind(weather_data.measurement_height)
|
||||||
|
.bind(&weather_data.area_type)
|
||||||
|
.bind(weather_data.point_wind_speed)
|
||||||
|
.bind(&weather_data.atmospheric_stability)
|
||||||
|
.bind(&weather_data.suitability_degree)
|
||||||
|
.bind(
|
||||||
|
serde_json::to_value(&weather_data.wind_direction)
|
||||||
|
.map_err(|e| format!("JSON 序列化失败: {}", e))?,
|
||||||
|
)
|
||||||
|
.bind(weather_data.average_wind_direction)
|
||||||
|
.bind(weather_data.wind_direction_standard_deviation)
|
||||||
|
.bind(
|
||||||
|
serde_json::to_value(&weather_data.wind_speed)
|
||||||
|
.map_err(|e| format!("JSON 序列化失败: {}", e))?,
|
||||||
|
)
|
||||||
|
.bind(weather_data.average_wind_speed)
|
||||||
|
.bind(&weather_data.wind_speed_suitability)
|
||||||
|
.bind(&weather_data.wind_direction_suitability)
|
||||||
|
.bind(&weather_data.overall_suitability)
|
||||||
|
.bind(&weather_data.inspection_type)
|
||||||
|
.bind(&weather_data.assignment_number)
|
||||||
|
.bind(weather_data.calculated_wind_speed)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok((id,)) => id,
|
||||||
|
Err(e) => {
|
||||||
|
return Err(format!("插入数据失败: {}", e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 4. 成功,返回插入的 ID
|
||||||
|
Ok(inserted_id)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn create_pool() -> Result<PgPool, sqlx::Error> {
|
pub async fn create_pool() -> Result<PgPool, sqlx::Error> {
|
||||||
dotenvy::dotenv().ok();
|
dotenvy::dotenv().ok();
|
||||||
let database_url = env::var("DATABASE_URL")
|
let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set in .env file");
|
||||||
.expect("DATABASE_URL must be set in .env file");
|
|
||||||
|
|
||||||
PgPool::connect(&database_url).await
|
PgPool::connect(&database_url).await
|
||||||
}
|
}
|
||||||
|
|||||||
120
src/main.rs
120
src/main.rs
@@ -7,6 +7,7 @@ use sqlx::postgres::PgPool;
|
|||||||
mod db;
|
mod db;
|
||||||
mod models;
|
mod models;
|
||||||
|
|
||||||
|
use db::insert_weather_data;
|
||||||
use models::WeatherData;
|
use models::WeatherData;
|
||||||
|
|
||||||
// 定义请求体结构
|
// 定义请求体结构
|
||||||
@@ -203,123 +204,32 @@ async fn post_weather_data(
|
|||||||
data: web::Json<WeatherData>,
|
data: web::Json<WeatherData>,
|
||||||
pool: web::Data<PgPool>,
|
pool: web::Data<PgPool>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
// 打印接收的数据
|
println!("Received weather data, preparing to insert into DB...");
|
||||||
println!("Received weather data: {:#?}", data);
|
|
||||||
|
|
||||||
// 1. 根据openid查询user_id
|
// 调用 db.rs 中的函数来处理数据库逻辑
|
||||||
let openid = &data.openid;
|
match insert_weather_data(pool.get_ref(), &data).await {
|
||||||
let query_user = r#"
|
Ok(inserted_id) => {
|
||||||
SELECT id FROM users WHERE openid = $1
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let user_id_result: Result<Option<(i32,)>, sqlx::Error> =
|
|
||||||
sqlx::query_as::<_, (i32,)>(query_user)
|
|
||||||
.bind(openid)
|
|
||||||
.fetch_optional(pool.get_ref())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let user_id = match user_id_result {
|
|
||||||
Ok(Some((id,))) => id,
|
|
||||||
Ok(None) => {
|
|
||||||
let error_msg = format!("未找到openid为 {} 的用户", openid);
|
|
||||||
eprintln!("{}", error_msg);
|
|
||||||
// 返回200状态码,但success为false
|
|
||||||
return HttpResponse::Ok().json(serde_json::json!({
|
|
||||||
"success": false,
|
|
||||||
"errcode": 404,
|
|
||||||
"errmsg": error_msg
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
let error_msg = format!("查询用户失败: {}", e);
|
|
||||||
eprintln!("{}", error_msg);
|
|
||||||
return HttpResponse::Ok().json(serde_json::json!({
|
|
||||||
"success": false,
|
|
||||||
"errcode": 500,
|
|
||||||
"errmsg": error_msg
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 2. 将天气数据插入数据库
|
|
||||||
let insert_query = r#"
|
|
||||||
INSERT INTO weather_data (
|
|
||||||
user_id, title, date, hour, min, longitude, latitude, daysincejanfirst,
|
|
||||||
theta, solardeclination, sunaltitude, overallcloudiness, lowcloudiness,
|
|
||||||
cloudindex, solarradiationlevel, hasmeasuredwindspeed, measuredwindspeed,
|
|
||||||
convertedwindspeed, measurementheight, areatype, pointwindspeed,
|
|
||||||
atmosphericstability, suitabilitydegree, winddirection, averagewinddirection,
|
|
||||||
winddirectionstandarddeviation, windspeed, averagewindspeed, windspeedsuitability,
|
|
||||||
winddirectionsuitability, overallsuitability, inspectiontype, assignmentnumber,
|
|
||||||
calculatedwindspeed
|
|
||||||
) VALUES (
|
|
||||||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19,
|
|
||||||
$20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34
|
|
||||||
) RETURNING id
|
|
||||||
"#;
|
|
||||||
|
|
||||||
// 转换经纬度为字符串
|
|
||||||
let longitude_str = data.longitude.to_string();
|
|
||||||
let latitude_str = data.latitude.to_string();
|
|
||||||
|
|
||||||
// 执行插入操作
|
|
||||||
let result = sqlx::query_as::<_, (i32,)>(insert_query)
|
|
||||||
.bind(user_id)
|
|
||||||
.bind(&data.title)
|
|
||||||
.bind(&data.date)
|
|
||||||
.bind(data.hours)
|
|
||||||
.bind(data.min)
|
|
||||||
.bind(&longitude_str)
|
|
||||||
.bind(&latitude_str)
|
|
||||||
.bind(data.day_since_jan_first)
|
|
||||||
.bind(data.theta)
|
|
||||||
.bind(data.solar_declination)
|
|
||||||
.bind(data.sun_altitude)
|
|
||||||
.bind(&data.overall_cloudiness)
|
|
||||||
.bind(&data.low_cloudiness)
|
|
||||||
.bind(&data.cloud_index)
|
|
||||||
.bind(data.solar_radiation_level as i32)
|
|
||||||
.bind(data.has_measured_wind_speed)
|
|
||||||
.bind(data.measured_wind_speed)
|
|
||||||
.bind(data.converted_wind_speed as i32)
|
|
||||||
.bind(data.measurement_height)
|
|
||||||
.bind(&data.area_type)
|
|
||||||
.bind(data.point_wind_speed)
|
|
||||||
.bind(&data.atmospheric_stability)
|
|
||||||
.bind(&data.suitability_degree)
|
|
||||||
.bind(serde_json::to_value(&data.wind_direction).unwrap())
|
|
||||||
.bind(data.average_wind_direction)
|
|
||||||
.bind(data.wind_direction_standard_deviation)
|
|
||||||
.bind(serde_json::to_value(&data.wind_speed).unwrap())
|
|
||||||
.bind(data.average_wind_speed)
|
|
||||||
.bind(&data.wind_speed_suitability)
|
|
||||||
.bind(&data.wind_direction_suitability)
|
|
||||||
.bind(&data.overall_suitability)
|
|
||||||
.bind(&data.inspection_type)
|
|
||||||
.bind(&data.assignment_number)
|
|
||||||
.bind(data.calculated_wind_speed)
|
|
||||||
.fetch_one(pool.get_ref())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match result {
|
|
||||||
Ok((inserted_id,)) => {
|
|
||||||
println!(
|
println!(
|
||||||
"Successfully inserted weather data with id: {}",
|
"Successfully inserted weather data with id: {}",
|
||||||
inserted_id
|
inserted_id
|
||||||
);
|
);
|
||||||
HttpResponse::Ok().json(serde_json::json!({
|
HttpResponse::Ok().json(serde_json::json!({
|
||||||
"success": true, // 前端期望的成功标识
|
"success": true,
|
||||||
"message": "Weather data inserted successfully",
|
"message": "Weather data inserted successfully",
|
||||||
"inserted_id": inserted_id,
|
"inserted_id": inserted_id,
|
||||||
"received_assignment": data.assignment_number
|
"received_assignment": data.assignment_number
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(error_msg) => {
|
||||||
let error_msg = format!("插入数据失败: {}", e);
|
eprintln!("Database operation failed: {}", error_msg);
|
||||||
eprintln!("{}", error_msg);
|
// 根据错误信息返回统一格式的错误响应
|
||||||
|
let mut errcode = 500;
|
||||||
|
if error_msg.starts_with("未找到openid") {
|
||||||
|
errcode = 404;
|
||||||
|
}
|
||||||
HttpResponse::Ok().json(serde_json::json!({
|
HttpResponse::Ok().json(serde_json::json!({
|
||||||
"success": false, // 前端期望的失败标识
|
"success": false,
|
||||||
"errcode": 500,
|
"errcode": errcode,
|
||||||
"errmsg": error_msg
|
"errmsg": error_msg
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user