zii hai 1 mes
pai
achega
a7c2632faa
Modificáronse 7 ficheiros con 259 adicións e 114 borrados
  1. 70 1
      src/api/ability.rs
  2. 41 27
      src/api/auth.rs
  3. 86 22
      src/api/device.rs
  4. 24 19
      src/api/flow_task.rs
  5. 4 3
      src/api/mod.rs
  6. 33 41
      src/api/user.rs
  7. 1 1
      src/main.rs

+ 70 - 1
src/api/ability.rs

@@ -1,6 +1,6 @@
 use axum::{extract::{State},Json};
 use super::{Ident,check_token};
-use crate::{AppState, LogLevel::*, datasource::Datasource, log};
+use crate::{AppState, LogLevel::*, api::JsonBack, datasource::Datasource, log};
 
 #[derive(serde::Serialize)]
 pub struct MqttBack{
@@ -152,6 +152,75 @@ pub async fn get_mqtt(
     return Json(MqttBack{errcode: 0, errmsg: None,mqttp:Some(mqtp),clientid:Some(mqid),mqttu:Some(mqtu)});
 }
 
+#[derive(serde::Deserialize)]
+pub struct DropD{
+    token: String,
+    device: u64
+}
+
+// #[derive(serde::Deserialize)]
+// pub struct DropDBack{
+//     errcode: u8,
+//     #[serde(skip_serializing_if = "Option::is_none")]
+//     errmsg: Option<String>
+
+// }
+
+
+pub async fn drop_device(
+    State(state): State<AppState>,
+    Json(d): axum::extract::Json<DropD>
+) -> Json<JsonBack> {
+    if let Err(e)=state.db_lite.query("select true from user where token=? and id=1", [d.token], |r|{r.get::<usize,bool>(0)}).await{
+        log(Warning, format!("error: {e}"));
+        return super::token_fail();
+    }
+    let sn = if let Ok(sn)=state.db_lite.query(
+        "select sn from device where id=?", 
+        [d.device], |r|{r.get::<usize,String>(0)}).await{
+        sn
+    }else{
+        return Json(JsonBack{errcode: 3000, errmsg: Some("数据库异常: 获取设备sn失败".to_string())});
+    };
+    let mut sqls=Vec::new();
+    let mqids = if let Ok(mqids) = state.db_lite.query_rows(
+        "select u.mqid from map_user_device m left join user u on u.id=m.did where m.did=?", 
+        [d.device], 
+        |r|{sqls.push("?");r.get::<usize,String>(0)}).await{mqids}else{return Json(JsonBack{errcode:3000,errmsg:Some("数据库异常: 获取用户mqtt-clientid失败".to_string())})};
+    
+    if let Err(e) = state.db_lite.execute("delete from map_user_device where did=?", [d.device]).await{log(Warning, format!("error: {e}"))}
+
+    if let Err(e) = state.db_lite.execute("update device set belongto=0 where did=?", [d.device]).await{log(Warning, format!("error: {e}"))}
+
+    match state.mq_detail{
+        Some(s) => {
+            match s.db_mq_map.execute(
+                format!("delete from sub where clientid in ({}) and topic in (?,?)",sqls.join(",")).as_str(), 
+                rusqlite::params_from_iter({
+                    let mut m = mqids.clone();
+                    m.push(format!("/wf/Iot/client/{}",sn));
+                    m.push(format!("{}/state",sn));
+                    m})).await{
+                Ok(n) => {log(Warning, format!("delete sub: {}",n))},
+                Err(e) => {log(Warning, format!("error: {e}"))}
+            };
+            match s.db_mq_map.execute(
+                format!("delete from pub where clientid in ({}) and topic in (?,?)",sqls.join(",")).as_str(), 
+                rusqlite::params_from_iter({
+                    let mut m = mqids.clone();
+                    m.push(format!("/wf/Iot/device/{}",sn));
+                    m.push(format!("{}/cmd",sn));
+                    m})).await{
+                Ok(n) => {log(Warning, format!("delete pub: {}",n))},
+                Err(e) => {log(Warning, format!("error: {e}"))}
+            };
+        }
+        None => {}
+    }
+
+    return super::errcode0();
+}
+
 #[test]
 fn test_f(){
 use tokio::io::{AsyncReadExt};

+ 41 - 27
src/api/auth.rs

@@ -73,16 +73,14 @@ pub async fn auth(
             // q.state
         )).send().await {
             Ok(a) => {
-                // log(Info, format!("dealing"));
+                log(Debug, format!("dealing"));
                 let v = a.text().await;
-                log(Debug, format!("dealing\n{:?}",v));
+                // log(Debuging, format!("dealing\n{:?}",v));
                 let v = if let Ok(v)=v {v}else {
                     return Redirect::to(format!("{}/null",crate::WEBP).as_str());
                 };
-                
                 match
                 serde_json::from_str::<WxGetToken>(v.as_str())
-                //  a.json::<WxGetToken>().await
                 {
                     Ok(b) => b,
                     Err(e) =>{
@@ -101,6 +99,7 @@ pub async fn auth(
     //     .unwrap_or("localhost:3000");
     log(Debuging, format!("in authing"));
     let token=super::token(32);
+    let mut bindfail:Option<&str>=None;
     let res = super::check_openid(&state, a.openid.clone()).await;
     if let Ok((id,mqid)) = res{
         // 用户已经注册 函数末尾发生跳转到主页
@@ -110,28 +109,35 @@ pub async fn auth(
         // 已注册时绑定设备
         if let Some(sn)= q.state.strip_prefix("did="){
             log(Debuging, format!("got did:  {}",sn));
-            if let Err(e) = state.db_lite.execute("update device set belongto=? where sn=? and belongto=0", (id,sn)).await{
-                println!("{e}");
-            }else if let Ok(did) = state.db_lite.query("select id from device where sn=?", [sn], |r|{r.get::<usize,i64>(0)}).await{
-            //  if let Some(did)=state.db_lite.last_insert_rowid().await.ok(){  // 错误位置:update不会给last_insert_rowid
-                if let Err(e) = state.db_lite.execute("insert into map_user_device (uid, did)values(?,?)", (id,did)).await{
-                    println!("{e}");
-                } else{
-                    if let Some(mq) = state.mq_detail{
-                        if let Err(e)=mq.db_mq_map.execute(
-                            "insert into pub (clientid,topic)values(?,?),(?,?)", 
-                            (mqid.clone(),format!("{}/cmd",sn),mqid.clone(),format!("/wf/Iot/device/{sn}"))).await{
-                            log(Warning, format!("on register with device: {e}"));
-                        };
-                        
-                        if let Err(e)=mq.db_mq_map.execute(
-                            "insert into sub (clientid,topic)values(?,?),(?,?)", 
-                            (mqid.clone(),format!("{}/state",sn),mqid.clone(),format!("/wf/Iot/client/{sn}"))).await{
-                            log(Warning, format!("on register with device: {e}"));
-                        };
-                    }
+            match state.db_lite.execute("update device set belongto=? where sn=? and belongto=0", (id,sn)).await{
+                Err(e) => {println!("{e}");bindfail=Some("&bindfail=true");}
+                Ok(n)=>{
+                    if n!=0{
+                        if let Ok(did) = state.db_lite.query("select id from device where sn=?", [sn], |r|{r.get::<usize,i64>(0)}).await{
+                        //  if let Some(did)=state.db_lite.last_insert_rowid().await.ok(){  // 错误位置:update不会给last_insert_rowid
+                            if let Err(e) = state.db_lite.execute("insert into map_user_device (uid, did)values(?,?)", (id,did)).await{
+                                println!("{e}");
+                            } else{
+                                bindfail=Some("&bindfail=false");
+                                if let Some(mq) = state.mq_detail{
+                                    if let Err(e)=mq.db_mq_map.execute(
+                                        "insert into pub (clientid,topic)values(?,?),(?,?)", 
+                                        (mqid.clone(),format!("{}/cmd",sn),mqid.clone(),format!("/wf/Iot/device/{sn}"))).await{
+                                        log(Warning, format!("on register with device: {e}"));
+                                    };
+                                    if let Err(e)=mq.db_mq_map.execute(
+                                        "insert into sub (clientid,topic)values(?,?),(?,?)", 
+                                        (mqid.clone(),format!("{}/state",sn),mqid.clone(),format!("/wf/Iot/client/{sn}"))).await{
+                                        log(Warning, format!("on register with device: {e}"));
+                                    };
+                                }
+                            }
+                        }
+                    } else{
+                        bindfail=Some("&bindfail=true");
+                    }; 
                 }
-            };  
+            }
         }
     } else if a.scope !="snsapi_userinfo"{
         // 用户未注册,跳转获取用户详细信息
@@ -181,9 +187,11 @@ pub async fn auth(
         if let Some(sn)= q.state.strip_prefix("did="){
             log(Debuging, format!("got did:  {}",sn));
             match state.db_lite.execute("update device set belongto=? where sn=? and belongto=0", (uid,sn)).await{
-                Err(e)=>{println!("{e}")},
+                Err(e)=>{println!("{e}");bindfail=Some("&bindfail=true");},
                 Ok(n ) => {
                     if n!=0{  // 设备绑定成功,update至少一条则记录并订阅
+                        bindfail=Some("&bindfail=false");
+                        log(Debuging, format!("got updated {n}"));
                         if let Ok(did) = state.db_lite.query(
                             "select id from device where sn=? and belongto=?",
                             (sn,uid), |r|{r.get::<usize,i64>(0)}).await{
@@ -206,6 +214,8 @@ pub async fn auth(
                                 };
                             }
                         }
+                    } else{
+                        bindfail=Some("&bindfail=true");
                     }
                 }
             };
@@ -217,6 +227,10 @@ pub async fn auth(
     // request::Request::get("body");
     // log(Info, format!("bad happend {:?}",res));
     log(Debug, format!("redirect back with token, state: {}",q.state));
-    return Redirect::to(format!("{}?token={}{}",crate::WEBP,token.clone(),if q.state.starts_with("?"){format!("#{}",q.state)}else{"".to_string()}).as_str());
+    return Redirect::to(format!("{}?token={}{}{}",
+        crate::WEBP,token.clone(),
+        if q.state.starts_with("?"){format!("#{}",q.state)}else{"".to_string()},
+        if let Some(s)= bindfail{s}else{""}).as_str()
+    );
     // return Redirect::to(format!("{}?token={}",crate::WEBP,token.clone()).as_str());
 }

+ 86 - 22
src/api/device.rs

@@ -93,15 +93,24 @@ pub async fn d_cancel_share(
     State(state): State<AppState>,
     Json(d): axum::extract::Json<Dshare>
 ) -> Json<JsonBack> {
-    let (uid,mqid) = match check_token(&state, d.token).await {
+    let (uid,_) = match check_token(&state, d.token).await {
         Ok(id) => {id},
         Err(_) => {
             return token_fail();
         }
     };
+    let mut sqls = Vec::new();
+    let mut users = if let Ok(users) = state.db_lite.query_rows(
+            "select u.mqid from map_user_device m left join user u on m.uid=u.id where did in (select id from device where belongto=?) and did=?", 
+            (uid,d.id), |r|{r.get::<usize,String>(0)}).await{
+                sqls.push("?");
+                users
+            }else{
+                Vec::new()
+            };
     if let Ok(n) = state.db_lite.execute(
-        "delete from map_user_device where did in (select id from device where belongto=?) and did=?",
-        [uid,d.id]).await {
+        "delete from map_user_device where did in (select id from device where belongto=?) and did=? and uid!=?",
+        [uid,d.id,uid]).await {
             if n ==0 {
                 return Json(JsonBack{errcode: 3000, errmsg: Some(format!("取消分享失败: 该设备不属于当前用户"))});
             } else if let Some(s) = state.mq_detail {
@@ -110,14 +119,30 @@ pub async fn d_cancel_share(
                     [d.id,uid], |r|{r.get::<usize,String>(0)}).await{
                         sn
                     }else{
-                        return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除设备失败: 设备不存在"))});
+                        return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除设备失败0: 设备不存在"))});
                     };
-                if let Err(e)=s.db_mq_map.execute("delete from pub where clientid=? and topic in (?,?)", (mqid.clone(),format!("{sn}/cmd",),format!("/wf/Iot/device/{sn}",))).await{
-                    log(Error, format!("删除设备失败: {e}"));
+                if !users.is_empty(){
+                    if let Err(e)=s.db_mq_map.execute(format!("delete from pub where clientid in ({}) and topic in (?,?)",sqls.join(",")).as_str(), rusqlite::params_from_iter({
+                        let mut u = users.clone();
+                        // mqid.clone(),format!("{sn}/cmd",),format!("/wf/Iot/device/{sn}",)
+                        u.push(format!("{sn}/cmd",));
+                        u.push(format!("/wf/Iot/device/{sn}",));
+                        log(Debuging, format!("{:?}",u));
+                        u
+                    })).await{
+                        log(Error, format!("删除设备失败1: {e}"));
+                    }
+                    if let Err(e)=s.db_mq_map.execute(format!("delete from pub where clientid in ({}) and topic in (?,?)",sqls.join(",")).as_str(), rusqlite::params_from_iter({
+                        // let mut u = users.clone();
+                        // (mqid,format!("{sn}/state",),format!("/wf/Iot/client/{sn}",))
+                        users.push(format!("{sn}/state",));
+                        users.push(format!("/wf/Iot/client/{sn}",));
+                        log(Debuging, format!("{:?}",users));
+                        users
+                    })).await{
+                        log(Error, format!("删除设备失败2: {e}"));
+                    } 
                 }
-                if let Err(e)=s.db_mq_map.execute("delete from sub where clientid=? and topic in (?,?)", (mqid,format!("{sn}/state",),format!("/wf/Iot/client/{sn}",))).await{
-                    log(Error, format!("删除设备失败: {e}"));
-                } 
             }
     }else {
         return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除用户设备关系失败"))});
@@ -138,10 +163,10 @@ pub async fn d_remove(
         }
     };
     let sn = if let Ok(sn)= state.db_lite.query(
-        "select sn from device where id=? and belongto=?", [d.id,uid], |r|{r.get::<usize,String>(0)}).await{
+        "select d.sn from map_user_device m left join device d on d.id=m.did where d.id=? and m.uid=?", [d.id,uid], |r|{r.get::<usize,String>(0)}).await{
             sn
     }else{
-        return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除设备失败: 设备不存在"))});
+        return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除设备失败c: 设备不存在"))});
     };
     
     if let Err(e) = state.db_lite.execute(
@@ -151,11 +176,11 @@ pub async fn d_remove(
     }
     if let Some(s)=state.mq_detail{
         // 移除旧关系
-        if let Err(e)=s.db_mq_map.execute("delete from pub where clientid=? and topic in (?,?)", (mqid.clone(),format!("{sn}/cmd",),format!("/wf/Iot/device/{sn}",))).await{
-            log(Error, format!("删除设备失败: {e}"));
+        if let Err(e)=s.db_mq_map.execute("delete from pub where clientid=? and topic in (?,?)", (mqid.clone(),format!("{sn}/cmd",),format!("/wf/Iot/device/{sn}"))).await{
+            log(Error, format!("删除设备失败a: {e}"));
         }
-        if let Err(e)=s.db_mq_map.execute("delete from sub where clientid=? and topic in (?,?)", (mqid,format!("{sn}/state",),format!("/wf/Iot/client/{sn}",))).await{
-            log(Error, format!("删除设备失败: {e}"));
+        if let Err(e)=s.db_mq_map.execute("delete from sub where clientid=? and topic in (?,?)", (mqid,format!("{sn}/state",),format!("/wf/Iot/client/{sn}"))).await{
+            log(Error, format!("删除设备失败b: {e}"));
         } 
     }
 
@@ -288,7 +313,9 @@ pub struct UTokenBack{
     #[serde(skip_serializing_if = "Option::is_none")]
     pub area: Option<Vec<Area>>,
     #[serde(skip_serializing_if = "Option::is_none")]
-    pub latest: Option<Vec<DV>>
+    pub latest: Option<Vec<DV>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub uinfo: Option<UInfo>
 }
 
 // #[derive(serde::Deserialize)]
@@ -330,6 +357,17 @@ pub struct UTokenBack{
 //     errcode0()
 // }
 
+#[derive(serde::Serialize)]
+pub struct UInfo{
+    errcode: u32,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    errmsg: Option<String>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    nickname: Option<String>,
+    #[serde(skip_serializing_if = "Option::is_none")]
+    headimgurl: Option<String>
+}
+
 pub async fn d_all(
     State(state): State<AppState>,
     Json(u): axum::extract::Json<super::Ident>
@@ -337,7 +375,7 @@ pub async fn d_all(
     let uid = if let Ok( (id,_)) = check_token(&state, u.token).await {
         id
     } else {
-        return Json(UTokenBack{errcode: 2000, errmsg: Some("鉴权失败: token无效".to_string()),devices: None,area: None,latest:None})
+        return Json(UTokenBack{errcode: 2000, errmsg: Some("鉴权失败: token无效".to_string()),devices: None,area: None,latest:None,uinfo:None})
     };
     let mut sqls = Vec::new();
     let mut devices: Vec<String> = Vec::new();
@@ -345,6 +383,29 @@ pub async fn d_all(
     Json(UTokenBack{
         errcode: 0,
         errmsg: None,
+        uinfo: match state.db_lite.query("select nickname, headimgurl from user where id=?", [uid], |r| {
+                Ok(
+                    UInfo{
+                        errcode: 0,
+                        errmsg: None,
+                        nickname: Some(r.get(0)?),
+                        headimgurl: Some(r.get(1)?)
+                    }
+                )
+            }).await{
+                Ok(u) => {Some(u)},
+                Err(e) => {
+                    log(Warning, format!("fail to take user info {e}"));
+                    return Json(UTokenBack{
+                        errcode: 3000,
+                        errmsg: Some(format!("设备信息获取失败")),
+                        devices: None,
+                        area: None,
+                        latest: None,
+                        uinfo: None
+                    })
+                }
+            },
         devices: Some(
             match state.db_lite.query_rows(
                 "select d.id,d.name,d.sn,d.area,d.belongto,d.info from device d left join map_user_device m on d.id=m.did where d.isdelete=0 and m.uid=?", 
@@ -369,7 +430,8 @@ pub async fn d_all(
                         errmsg: Some(format!("设备信息获取失败")),
                         devices: None,
                         area: None,
-                        latest: None
+                        latest: None,
+                        uinfo: None
                     })
                 }
             }
@@ -392,7 +454,8 @@ pub async fn d_all(
                         errmsg: Some(format!("设备信息获取失败")),
                         devices: None,
                         area: None,
-                        latest: None
+                        latest: None,
+                        uinfo: None
                     })
                 }
             }
@@ -426,9 +489,10 @@ pub async fn d_all(
                         beep: r.get(17)?,
                     })
                 }).await.ok()
-        },
-        None =>None
-        }
+            },
+                None =>None
+            },
+        
         }
     )
 }

+ 24 - 19
src/api/flow_task.rs

@@ -87,7 +87,7 @@ pub async fn checkout_flow_task_of_share_device(
         }
     };
     let (the_id,sn, typo,interval, createby) = match state.db_lite.query(
-        "select did,sn,typo,strftime('%s','now')-strftime('%s',createtime),createby from flow_task_share where ticket=? and isdelete=0",
+        "select f.did,d.sn,f.typo,strftime('%s','now')-strftime('%s',createtime),f.createby from flow_task_share f left join device d on f.did=d.id where f.ticket=? and f.isdelete=0",
         [
             // params.linkrand.clone()
             u.linkrand.clone()
@@ -140,38 +140,43 @@ pub async fn checkout_flow_task_of_share_device(
     // 为1时分享设备,为2时转让设备,此处添加设备与新用户的关系
     else if typo == 1 || typo == 2 {
         match state.db_lite.execute("insert into map_user_device(uid,did)values(?,?)", [uid, the_id]).await{
-            Ok(_) => {
-                if let Some(ref s)=state.mq_detail{
-                    // 插入新关系
-                    if let Err(e)=s.db_mq_map.execute("insert into pub (clientid,topic)values(?,?),(?,?)", (mqid.clone(),format!("{sn}/cmd",),mqid.clone(),format!("/wf/Iot/device/{sn}",))).await{
-                        log(Error, format!("添加设备失败: {e}"));
-                    }
-                    if let Err(e)=s.db_mq_map.execute("insert into sub (clientid,topic)values(?,?),(?,?)", (mqid.clone(),format!("{sn}/state",),mqid,format!("/wf/Iot/client/{sn}",))).await{
-                        log(Error, format!("添加设备失败: {e}"));
-                    }
-                }
-            },
+            Ok(_) => {/*正常插入,可以跳过*/},
             Err(e) => if e==""{/*Unique异常跳过*/}else{ return Json(JsonBack{errcode: 3000, errmsg: Some(format!("添加设备分享关系失败: {e}"))});}
         };    
+        match state.db_lite.execute("delete from flow_task_share where ticket=?", [u.linkrand.clone()]).await{
+            Ok(_) => {},
+            Err(e) => {println!("when delete transform flow got error: {e}")}
+        }
+        // 添加监听
+        if let Some(ref s)=state.mq_detail{
+            // 插入新关系
+            if let Err(e)=s.db_mq_map.execute("insert into pub (clientid,topic)values(?,?),(?,?)", (mqid.clone(),format!("{sn}/cmd",),mqid.clone(),format!("/wf/Iot/device/{sn}",))).await{
+                log(Error, format!("添加设备失败: {e}"));
+            }
+            if let Err(e)=s.db_mq_map.execute("insert into sub (clientid,topic)values(?,?),(?,?)", (mqid.clone(),format!("{sn}/state",),mqid,format!("/wf/Iot/client/{sn}",))).await{
+                log(Error, format!("添加设备失败: {e}"));
+            }
+        }
     } else {
         return Json(JsonBack{errcode: 3000, errmsg: Some("分享流程类型错误".to_string())});
     }
 
     // 转让设备需要将belongto更新
     if typo == 2{
-        let mqold = if let Ok(mqid) = state.db_lite.query("select u.mqid from device d left join user u on u.id=d.belongto where id=?", [the_id], |r|Ok(r.get::<usize, String>(0)?)).await{
-            mqid
+        let (mqold, effected) = if let Ok(ans) = state.db_lite.query(
+            "select d.mqid, count(*) from (select u.mqid mqid, d.id id from device d left join user u on u.id=d.belongto where d.id=?)d left join map_user_device m on d.id=m.did", 
+            [the_id], |r|Ok((r.get::<usize, String>(0)?,r.get::<usize, u64>(1)?,))).await{
+            ans
         }else{
-            String::new()
+            (String::new(),0)
         };
+        if effected!=1{
+            return Json(JsonBack { errcode: 3000, errmsg: Some(format!("该设备被分享状态占用,目前有{effected}条分享")) });
+        }
         match state.db_lite.execute("update device set belongto=? where id=?", [uid, the_id]).await{
             Ok(_) => {},
             Err(e) => return Json(JsonBack{errcode: 3000, errmsg: Some(format!("更新设备分享关系失败: {e}"))}),
         }
-        match state.db_lite.execute("delete from flow_task_share where ticket=?", [u.linkrand.clone()]).await{
-            Ok(_) => {},
-            Err(e) => {println!("when delete transform flow got error: {e}")}
-        }
         if let Some(s)=state.mq_detail{
             // 移除旧关系
             if let Err(e)=s.db_mq_map.execute("delete from pub where clientid=? and topic in (?,?)", (mqold.clone(),format!("{sn}/cmd",),format!("/wf/Iot/device/{sn}",))).await{

+ 4 - 3
src/api/mod.rs

@@ -9,7 +9,8 @@ pub mod ability;
 mod code_helper;
 
 use rand::Rng;
-use crate::datasource::Datasource;
+use reqwest::header::WARNING;
+use crate::{datasource::Datasource, log, LogLevel::*};
 
 #[derive(serde::Deserialize)]
 pub struct Ident{
@@ -59,8 +60,8 @@ pub async fn example(axum::extract::State(_): axum::extract::State<crate::AppSta
 pub async fn check_token(state: &crate::AppState, token: String) -> Result<(u64,String),()>{
     state.db_lite.query(
         "select id,mqid from user where token=? and isdelete=0", 
-        [token],  // 这里不能写作 rusqlite::params![token] 
-        |r|{Ok((r.get::<usize,u64>(0)?,r.get::<usize,String>(1)?))}).await.map_err(|e| println!("{e}"))
+        [token.clone()],  // 这里不能写作 rusqlite::params![token] 
+        |r|{Ok((r.get::<usize,u64>(0)?,r.get::<usize,String>(1)?))}).await.map_err(|e| log(Warning,format!("{token},{e}")))
 }
 
 pub async fn check_openid(state: &crate::AppState, openid: String) -> Result<(u64,String),()>{

+ 33 - 41
src/api/user.rs

@@ -195,6 +195,8 @@ pub struct Ulist{
     #[serde(flatten)]
     page: Option<Page>,
     #[serde(skip_serializing_if = "Option::is_none")]
+    ids: Option<Vec<i64>>,
+    #[serde(skip_serializing_if = "Option::is_none")]
     nickname: Option<String>,
     #[serde(skip_serializing_if = "Option::is_none")]
     group: Option<String>
@@ -218,7 +220,8 @@ pub async fn u_list(
     match state.db_lite.query_rows(
         format!("select u.id, u.uname, u.nickname, strftime('%s',  u.lastlogin)*1000, strftime('%s', u.createtime)*1000 from user u where isdelete=0{}{} limit ? offset ?",
         if let Some(ref filter) = u.nickname {params.push(Box::new(filter.clone())); " and u.nickname like ?"} else {""},
-        if let Some(ref filter) = u.group {params.push(Box::new(filter.clone())); " and u.group like ?"} else {""}
+        if let Some(ref filter) = u.group {params.push(Box::new(filter.clone())); " and u.group like ?"} else {""},
+        // if let Some(ref filter) = u.ids {params.extend(filter.clone()); " and u.group like ?"} else {""}
     ).as_str(),
      rusqlite::params_from_iter({params.push(Box::new(size));params.push(Box::new(size*(page-1)));params}) , |r| {
             Ok(Uedit{
@@ -267,43 +270,32 @@ pub async fn u_list(
 //         data: None
 // });
 // }
-#[derive(Serialize)]
-pub struct UInfo{
-    errcode: u32,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    errmsg: Option<String>,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    nickname: Option<String>,
-    #[serde(skip_serializing_if = "Option::is_none")]
-    headimgurl: Option<String>
-}
-
-pub async fn u_info(
-    State(state): State<AppState>,
-    Json(u): axum::extract::Json<super::Ident>
-) -> Json<UInfo>{
-    let (uid,_) = match check_token(&state, u.token).await{
-        Ok(uid) => uid,
-        Err(_) => return Json(UInfo { errcode: 2000, errmsg: Some("鉴权失败: token失效".to_string()), nickname: None, headimgurl: None })
-    };
-    match state.db_lite.query("select nickname, headimgurl from user where id=?", [uid], |r| {
-        Ok(
-            UInfo{
-                errcode: 0,
-                errmsg: None,
-                nickname: Some(r.get(0)?),
-                headimgurl: Some(r.get(1)?)
-            }
-        )
-    }).await {
-        Ok(ans) => Json(ans),
-        Err(e) => {
-            Json(UInfo{
-                errcode: 3000,
-                errmsg: Some(format!("用户信息获取失败: {e}")),
-                nickname: None,
-                headimgurl: None
-            })
-        }
-    }
-}
+// pub async fn u_info(
+//     State(state): State<AppState>,
+//     Json(u): axum::extract::Json<super::Ident>
+// ) -> Json<UInfo>{
+//     let (uid,_) = match check_token(&state, u.token).await{
+//         Ok(uid) => uid,
+//         Err(_) => return Json(UInfo { errcode: 2000, errmsg: Some("鉴权失败: token失效".to_string()), nickname: None, headimgurl: None })
+//     };
+//     match state.db_lite.query("select nickname, headimgurl from user where id=?", [uid], |r| {
+//         Ok(
+//             UInfo{
+//                 errcode: 0,
+//                 errmsg: None,
+//                 nickname: Some(r.get(0)?),
+//                 headimgurl: Some(r.get(1)?)
+//             }
+//         )
+//     }).await {
+//         Ok(ans) => Json(ans),
+//         Err(e) => {
+//             Json(UInfo{
+//                 errcode: 3000,
+//                 errmsg: Some(format!("用户信息获取失败: {e}")),
+//                 nickname: None,
+//                 headimgurl: None
+//             })
+//         }
+//     }
+// }

+ 1 - 1
src/main.rs

@@ -145,7 +145,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
 
             .route("/device", post(api::device::d_all))
 
-            .route("/user/info", post(api::user::u_info))
+            // .route("/user/info", post(api::user::u_info))
             .route("/user/edit", post(api::user::u_edit))
             .route("/user/list", post(api::user::u_list))