基于Rust语言的Rocket框架和Sqlx库开发WebAPI项目记录(五)

登录处理代码

在src目录新建login_handle.rs文件

目录结构如下:

project

|---src

|---params //封装参数结构体模块

|---req.rs //封装请求参数结构体

|---resp.rs //封装返回数据结构体

|---result_parse.rs //解析返回参数结构体

|---mod.rs //导出模块

|---common //公共模块

|---db.rs //构造数据库连接池

|---jwt.rs //处理token

|---mistake.rs //处理错误

|---util.rs //工具函数

|---mod.rs //导出模块

|---logic //业务逻辑模块

|---wechat.rs //处理业务

|---mod.rs //导出模块

|---login_handle.rs //登录处理函数

login_handle.rs代码如下:

rust 复制代码
use crate::common::db;
use crate::params::req;
use crate::params::req::Userparam;
use crate::params::resp;
use crate::common::utils::get_uuid;
use crate::common::jwt::get_token;


use rocket::get;
use rocket_db_pools::Connection;
use rocket_db_pools::sqlx::{self,Row};
use rocket::serde::json::{Value,Json,json};


//注册
pub async fn register(mut db:  Connection<db::Prodb>,regpram:Json<req::Userparam>)->Json<resp::Regresp> {

    let userid=get_uuid();
    let sql = sqlx::query("insert into users (uname,id) values ($1,$2)")
        .bind(&regpram.uname)
        .bind(&userid)
        .execute(& mut **db).await;
    match sql {
        Ok(_result) => {
            Json(
              resp::Regresp { code:1,
              message:"Success".to_string(),
              uid:userid
            })
        },
        Err(err) => {
            Json(
                resp::Regresp { code:0,
                message:err.to_string(),
                uid:"null".to_owned()
              })
        }
    }
}

//获取用户id

pub async fn get_id(mut db: Connection<db::Prodb>,uname:String)->String {


    let uid = sqlx::query("select id from users where uname=$1")
        .bind(&uname)
        .fetch_one(&mut **db)
        .await.unwrap().get(0);

       return uid;
        
   
}



//验证
#[get("/verify/<uname>")]
pub async fn verify(mut db: Connection<db::Prodb>,uname:String)->Value {

    let count = sqlx::query("select count(*) from users where uname=$1")
        .bind(&uname)
        .fetch_one(&mut **db)
        .await;


    match count{

        Ok(a)=>{  //非空行,有数据
            let num:i64 =a.get(0);
            if num>0{
                let id=get_id(db, uname.clone()).await;
                let user=Userparam{
                    uname:uname.clone(),
                    id:id
                };
              get_token(Json(user)).await
            }else{
                let userid=get_uuid();
                let regparam=Userparam{
                    uname:uname.clone(),
                    id:userid
                };
               let reg:Json<resp::Regresp>= register(db, Json(regparam)).await;
               let uid=&reg.uid;
                if reg.code==1{
                    
                    let user=Userparam{
                        uname:uname,
                        id:uid.to_owned()
                    };
                    get_token(Json(user)).await
                }else{
                    json!(
                        resp::Resp { code:0,
                        message:"认证失败!".to_string(),
                      })
                }
            }
        },
        Err(_b)=>{  //空行,无数据
            let userid=get_uuid();
            let regparam=Userparam{
                uname:uname.clone(),
                id:userid
            };
            let reg:Json<resp::Regresp>= register(db, Json(regparam)).await;
            let uid=&reg.uid;
            if reg.code==1{
            
                let user=Userparam{
                    uname:uname,
                    id:uid.to_owned()
                };
                get_token(Json(user)).await
            }else{
                json!(
                    resp::Resp { code:0,
                    message:"认证失败!".to_string(),
                })
            }
        }
    }

  
}
CRUD与上传文件处理代码

在src目录新建xxx_handle.rs文件

目录结构如下:

project

|---src

|---params //封装参数结构体模块

|---req.rs //封装请求参数结构体

|---resp.rs //封装返回数据结构体

|---result_parse.rs //解析返回参数结构体

|---mod.rs //导出模块

|---common //公共模块

|---db.rs //构造数据库连接池

|---jwt.rs //处理token

|---mistake.rs //处理错误

|---util.rs //工具函数

|---mod.rs //导出模块

|---logic //业务逻辑模块

|---wechat.rs //处理业务

|---mod.rs //导出模块

|---login_handle.rs //登录处理函数

|---xxx_handle.rs //CRUD与上传文件处理函数示例

xxx_handle.rs处理函数代码示例:

rust 复制代码
use rocket::{post,get};
use rocket_db_pools::Connection;
use rocket_db_pools::sqlx::{self,Row};
use rocket::serde::json::Json;
use sqlx::postgres::PgRow;
use rocket::form::Form;
use std::collections::HashMap;
use std::env;



use crate::logic::wechat::{ocr,parse_ocr,del_img};
use crate::common::db;
use crate::params::req::{self, UploadImg};
use crate::params::resp;
use crate::common::utils::get_uuid;
use crate::common::jwt::Token;



//上传文件处理
#[post("/upload",data="<img>")]
pub async fn upload_file(mut img:Form<UploadImg<'_>>)->Result<Json<HashMap<String, String>>,std::io::Error>{
    //处理图片上传逻辑
    //获取项目部署路径
    let exe_path=env::current_exe().unwrap();
    let mut path=exe_path
    .parent()
    .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::Other, "No parent directory found"))
    .unwrap()
    .to_path_buf();
    //拼接路径
    path.push("tmp");
    path.push(img.name);
    let url=path.to_str().unwrap();
   //将临时文件移动到路径
    img.file.persist_to(url).await.unwrap();
    //图片服务器
    let http_img=String::from("https://www.xxxyyy.cn/images/")+img.name;
    //返回识别数据
    let datas= ocr(&http_img).await ;
    if let Ok(data)=datas{
       let parser =parse_ocr(&data).await;
       return Ok(Json(parser));

    }else{
        println!("OCR文本识别失败,请重新再试");
        //删除临时图片
        del_img(String::from(url)).await.unwrap();
        let resp=[("code".to_string(),"0".to_string()),("msg".to_string(),"识别失败".to_string())];
    
        return Ok(Json(HashMap::from(resp)));
    }

}


//插入数据
#[post("/insert",data="<liverpram>")]
pub async fn insert_liver(mut db: Connection<db::Prodb>,liverpram:Json<req::Liverparam<'_>>,auth:Token)->Json<resp::Resp> {

    //获取uuid
    let liverid=get_uuid();
    //获取从token中解析出来的用户信息
    let uname=auth.uname;
    let sql = sqlx::query("insert into livers (livervalue,checktime,uid,id) values ($1,$2,$3,$4)")
        .bind(liverpram.livervalue)
        .bind(liverpram.checktime)
        .bind(uname)
        .bind(liverid)
        .execute(&mut **db).await;
    match sql {
        Ok(_result) => {
            Json(
              resp::Resp { code:1,
              message:"Success".to_string(),
            })
        },
        Err(err) => {
            Json(
                resp::Resp { code:0,
                message:err.to_string(),
              })
        }
    }
}

//删除数据
#[get("/delete/<id>")]
pub async fn delete_liver(mut db: Connection<db::Prodb>,id:String,_auth:Token)->Json<resp::Resp> {


    let sql = sqlx::query("delete from livers where id=$1")
        .bind(id)
        .execute(&mut **db).await;
    match sql {
        Ok(_result) => {
            Json(
              resp::Resp { code:1,
              message:"Success".to_string(),
            })
        },
        Err(err) => {
            Json(
                resp::Resp { code:0,
                message:err.to_string(),
              })
        }
    }
}

//返回数据
//返回liver数组--倒序
#[get("/list")]
pub async fn list_liver(mut db: Connection<db::Prodb>,auth:Token) -> Json<Vec<resp::Listliver>> {

    let uname=auth.uname;
    let rows =sqlx::query("SELECT id,uid,livervalue,checktime FROM livers where uid=$1 order by checktime desc limit 7").bind(uname);

    let list:Result<Vec<resp::Listliver>,sqlx::Error>=rows.map(|r:PgRow|
        resp::Listliver{
            livervalue:r.get("livervalue"),
            checktime:r.get("checktime"),
            uid:r.get("uid"),
            id:r.get("id")

         }

    )
    .fetch_all(&mut **db).await;
    match list {
        Ok(data)=>{
            Json(data)
        },
        Err(_err)=>{
            Json(Vec::new())
        }
        
    }
   
    
}


//返回AFP数组--正序
#[get("/listasc")]
pub async fn list_liver_asc(mut db: Connection<db::Prodb>,auth:Token) -> Json<Vec<resp::Listliver>> {

    let uname=auth.uname;
    let rows =sqlx::query("select id,uid,livervalue,checktime from (SELECT id,uid,livervalue,checktime FROM livers where uid=$1 order by checktime desc limit 7) order by checktime asc").bind(uname);

    let list:Result<Vec<resp::Listliver>,sqlx::Error>=rows.map(|r:PgRow|
        resp::Listliver{
            livervalue:r.get("livervalue"),
            checktime:r.get("checktime"),
            uid:r.get("uid"),
            id:r.get("id")

         }

    )
    .fetch_all(&mut **db).await;
    match list {
        Ok(data)=>{
            Json(data)
        },
        Err(_err)=>{
            Json(Vec::new())
        }
        
    }

    
    
}


//返回AFP数组--倒序
#[get("/listall")]
pub async fn list_liver_all(mut db: Connection<db::Prodb>,auth:Token) -> Json<Vec<resp::Listliver>> {

    let uname=auth.uname;
    let rows =sqlx::query("SELECT id,uid,livervalue,checktime FROM livers where uid=$1 order by checktime desc").bind(uname);

    let list:Result<Vec<resp::Listliver>,sqlx::Error>=rows.map(|r:PgRow|
        resp::Listliver{
            livervalue:r.get("livervalue"),
            checktime:r.get("checktime"),
            uid:r.get("uid"),
            id:r.get("id")

         }

    )
    .fetch_all(&mut **db).await;

    match list{
        Ok(data)=>{
            Json(data)
        },
        Err(_err)=>{
            Json(Vec::new())
        }
    }
    
    
}


//返回AFP数组--正序
#[get("/listallasc")]
pub async fn list_liver_all_asc(mut db: Connection<db::Prodb>,auth:Token) -> Json<Vec<resp::Listliver>> {

    let uname=auth.uname;
    let rows =sqlx::query("SELECT id,uid,livervalue,checktime FROM livers where uid=$1 order by checktime asc").bind(uname);

    let list:Result<Vec<resp::Listliver>,sqlx::Error>=rows.map(|r:PgRow|
        resp::Listliver{
            livervalue:r.get("livervalue"),
            checktime:r.get("checktime"),
            uid:r.get("uid"),
            id:r.get("id")

         }

    )
    .fetch_all(&mut **db).await;

    match list{
        Ok(data)=>{
            Json(data)
        },
        Err(_err)=>{
            Json(Vec::new())
        }
    }  
    
}
相关推荐
Bruce_Liuxiaowei1 分钟前
Python 实例赋值遮蔽类属性:一个从不报错的静默陷阱
开发语言·python·语法糖
IT_陈寒7 分钟前
Java线程池用错参数,我的服务居然悄悄崩溃了
前端·人工智能·后端
光影少年18 分钟前
Express 中间件原理
后端·node.js·express
梦醒沉醉28 分钟前
std1.97.1——cmp模块细览
rust
aramae1 小时前
MySQL内置函数(7)
开发语言·笔记·后端·mysql·其他
徐小夕2 小时前
存量.doc 文档怎么办?JitWord 开源转换库打通旧文档到在线协同全链路
后端·架构·github
ee又momo2 小时前
一次 JWT Token 过期续期的踩坑记录
后端
二月龙2 小时前
App 瘦身实战:图片、so 库、资源压缩,安装包体积减小 40%
后端
大勇前进2 小时前
Kotlin 协程实战避坑:90% 的人都会踩的生命周期泄漏问题
后端
苏三说技术3 小时前
Spring AI、LangChain4j、AgentScope、Embabel,哪个AI框架更好?
后端