| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- use crate::{AppState, log, LogLevel::*};
- use super::{JsonBack, errcode0, token};
- use super::{token_fail,check_token};
- use crate::datasource::Datasource;
- use serde::{Serialize, Deserialize};
- use axum::{Json,extract::{State}, http::HeaderMap};
- #[derive(Deserialize)]
- pub struct TaskOfDeviceShareOrTransfer{
- token: String,
- id: u64,
- r#type: u8,
- }
- #[derive(Serialize)]
- pub struct UrlBack{
- errcode: u16,
- errmsg: Option<String>,
- url: Option<String>,
- }
- #[allow(unused_variables)]
- pub async fn new_flow_task_share_device(
- headers: HeaderMap,
- State(state): State<AppState>,
- Json(u): axum::extract::Json<TaskOfDeviceShareOrTransfer>
- ) -> Json<UrlBack> {
- let (uid,_) = match check_token(&state, u.token).await {
- Ok(id) => {id},
- Err(_) => {
- return Json(UrlBack{errcode: 3000, errmsg: Some(format!("鉴权失败: token失效")),url:None});
- }
- };
- match u.r#type{
- 0|1|2 => {},
- _ => {
- return Json(UrlBack{errcode: 3000, errmsg: Some(format!("参数错误: type应为0、1、2")),url:None});
- }
- }
- let mut tryno=0;
- let linkrand = token(32);
- while tryno<5 && match state.db_lite.execute(
- "insert into flow_task_share (did, typo, ticket,createby)values (?,?,?,?)",
- (u.id,u.r#type,linkrand.clone(),uid)).await{
- Ok(_) => false,
- Err(e) =>
- if e==""{true} // execute时如果遇到Unique异常时会将异常处理为空字符串
- else{return Json(UrlBack{errcode: 3000, errmsg: Some(format!("分享流程创建失败: {e}")),url:None})},
- }
- {
- tryno+=1;
- };
- if tryno==5{
- return Json(UrlBack{errcode: 3000, errmsg: Some(format!("分享流程创建失败: 反复重试失败")),url: None});
- }
-
- // 获取主机名
- // let host = format!("https://{}",headers.get("host")
- // .and_then(|hv| hv.to_str().ok())
- // .unwrap_or("localhost:3000"));
- let host = crate::WEBP;
- Json(UrlBack{errcode: 0, errmsg: None,url:Some(format!("{host}?linkrand={linkrand}"))})
- }
- // #[derive(Deserialize)]
- // pub struct QueryParams {
- // linkrand: String,
- // }
- #[derive(Deserialize)]
- pub struct CheckoutShare {
- token: String,
- linkrand: String,
- }
- pub async fn checkout_flow_task_of_share_device(
- State(state): State<AppState>,
- // Query(params): Query<QueryParams>,
- Json(u): Json<CheckoutShare>
- ) -> Json<JsonBack> {
- let (uid, mqid) = match check_token(&state, u.token).await {
- Ok(uid) => uid,
- Err(_) => {
- return token_fail();
- }
- };
- let (the_id,sn, typo,interval, createby) = match state.db_lite.query(
- "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()
- ], |r|Ok((r.get::<usize, u64>(0)?,r.get::<usize, String>(1)?,r.get::<usize, u8>(2)?,r.get::<usize, u64>(3)?,r.get::<usize, u64>(4)?))).await{
- Ok(a) => a,
- Err(_) => return Json(JsonBack{errcode: 3000, errmsg: Some(
- "未找到分享流程".to_string()
- // format!("未找到分享流程 {} {e}",params.ticket.clone())
- )}),
- };
- if interval > 30*60 /* interval为当前时间减去createtime的秒数 */ {
- match state.db_lite.execute(
- "delete from flow_task_share where ticket=?",
- // "update flow_task_share set isdelete=1 where ticket=?",
- [u.linkrand.clone()]).await{
- Ok(_) => {},
- Err(e) => return Json(JsonBack{errcode: 3000, errmsg: Some(format!("删除分享流程失败: {e}"))}),
- };
- return Json(JsonBack{errcode: 3000, errmsg: Some("分享流程已过期".to_string())});
- }
- // 为2时转让设备,需要移除原用户与设备的关系
- if typo == 2{
- if let Err(e) = state.db_lite.execute("delete from map_user_device where uid=? and did=?", (createby, the_id)).await{
- return Json(JsonBack{errcode: 3000, errmsg: Some(format!("转让时删除设备关系失败: {e}"))});
- }
- }
- // 为0时分享区域
- if typo == 0{
- match state.db_lite.execute("insert into map_user_area(uid,aid)values(?,?)", [uid, the_id]).await{
- Ok(i) => {
- log(Debug, format!("影响一级区域数量{i}个"));
- },
- Err(e) => if e==""{/*Unique异常跳过 */} else {return Json(JsonBack{errcode: 3000, errmsg: Some(format!("添加区域分享关系失败: {e}"))});},
- };
- match state.db_lite.execute("insert into map_user_area(uid,aid) select ?,id from area where sup=? and id not in (select aid from map_user_area where uid=?)", [uid, the_id,uid]).await{
- Ok(i) => {
- log(Debug, format!("影响二级区域数量{i}个"));
- },
- Err(e) => if e==""{/*Unique异常跳过 */} else {return Json(JsonBack{errcode: 3000, errmsg: Some(format!("添加区域下级分享关系失败: {e}"))})},
- };
- match state.db_lite.execute("insert into map_user_device(uid,did) select ?,device.id from device where area in (select id from area where area.sup=?) and device.id not in (select did from map_user_device where uid=?)", [uid, the_id,uid]).await{
- Ok(i) => {
- log(Debug, format!("影响设备数量{i}个"));
- },
- Err(e) =>if e==""{/*Unique异常跳过 */} else { return Json(JsonBack{errcode: 3000, errmsg: Some(format!("添加区域下全部设备关系失败: {e}"))})},
- };
- }
- // 为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(_) => {/*正常插入,可以跳过*/},
- 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, 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(),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}"))}),
- }
- 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{
- log(Error, format!("删除设备失败: {e}"));
- }
- if let Err(e)=s.db_mq_map.execute("delete from sub where clientid=? and topic in (?,?)", (mqold,format!("{sn}/state",),format!("/wf/Iot/client/{sn}",))).await{
- log(Error, format!("删除设备失败: {e}"));
- }
- }
- } else {
- match state.db_lite.execute("delete from flow_task_share where strftime('%s','now')-strftime('%s',createtime)>30*60", []).await{
- Ok(_) => {},
- Err(e) => {println!("when delete extra flow got error: {e}")}
- }
- }
- errcode0()
- }
|