| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784 | 
							- //! 盛大数据模型
 
- use crate::{
 
-     backend::{self},
 
-     config::Config,
 
-     gmssl, Sign, Verify,
 
- };
 
- use anyhow::Context;
 
- use axum::{response::IntoResponse, Json};
 
- use md5::{Digest, Md5};
 
- use serde::de::DeserializeOwned;
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct PubReqHead {
 
-     pub app_id: String,
 
-     pub method: String,
 
-     pub sign_type: String,
 
-     pub sign: String,
 
-     pub timestamp: String, // yyyy-MM-dd HH:mm:ss
 
-     pub version: String,
 
-     pub request_id: String,
 
-     pub biz_content: String,
 
- }
 
- pub trait TryFromPubHeadConfig: Sized {
 
-     fn try_from_pub_req_head_config(head: &PubReqHead, config: &Config) -> anyhow::Result<Self>;
 
- }
 
- impl<T> TryFromPubHeadConfig for T
 
- where
 
-     T: Sized + DeserializeOwned + crate::Verify,
 
- {
 
-     fn try_from_pub_req_head_config(head: &PubReqHead, config: &Config) -> anyhow::Result<Self> {
 
-         let req: T = head.decopy(config)?;
 
-         req.verify(config).context("验证出错")?;
 
-         Ok(req)
 
-     }
 
- }
 
- impl crate::Verify for PubReqHead {
 
-     #[tracing::instrument(skip_all, fields(PubReqHead=?self))]
 
-     fn verify(&self, config: &Config) -> anyhow::Result<()> {
 
-         if self.sign_type != "md5"
 
-             || self.app_id != config.sd_config.app_id
 
-             || self.method != "sd.tovc.recharge"
 
-         {
 
-             return Err(anyhow::Error::msg("PubReqHead Verify Value Error"));
 
-         }
 
-         match hex::decode(&self.sign) {
 
-             Ok(o) => {
 
-                 let new_sign = self.sign_var(config);
 
-                 if o == new_sign {
 
-                     Ok(())
 
-                 } else {
 
-                     Err(anyhow::Error::msg("sign 不匹配"))
 
-                 }
 
-             }
 
-             Err(e) => {
 
-                 tracing::error!("verify: {self:?} error: {e}");
 
-                 Err(anyhow::Error::msg(format!(
 
-                     "PubReqHead Verify Value sign hex::decode Error: {e:#?}"
 
-                 )))
 
-             }
 
-         }
 
-     }
 
- }
 
- impl Default for PubReqHead {
 
-     fn default() -> Self {
 
-         let time_format = time::macros::format_description!(
 
-         "[year]-[month padding:zero]-[day padding:zero] [hour padding:zero]:[minute padding:zero]:[second padding:zero]"
 
-     );
 
-         let offset = time::UtcOffset::from_hms(8, 0, 0).unwrap();
 
-         let now = time::OffsetDateTime::now_utc().to_offset(offset);
 
-         Self {
 
-             app_id: "".to_string(),
 
-             method: "".to_string(),
 
-             sign_type: "md5".to_string(),
 
-             sign: "".to_string(),
 
-             timestamp: now.format(time_format).unwrap(),
 
-             version: "v1.0".to_string(),
 
-             request_id: "".to_string(),
 
-             biz_content: "".to_string(),
 
-         }
 
-     }
 
- }
 
- macro_rules! str_per {
 
-     ( $($p:ident).*) => {
 
-         (str_per!(@internal $($p).*), $($p).*)
 
-     };
 
-     (@internal $p:ident ) => {
 
-         {
 
-             let s = stringify!($p);
 
-             let mut str = String::new();
 
-             let mut capitalize = false;
 
-             for i in s.chars(){
 
-                 if i == '_'{
 
-                     capitalize = true;
 
-                 }else if capitalize {
 
-                     str.push(i.to_ascii_uppercase());
 
-                     capitalize = false;
 
-                 }else{
 
-                     str.push(i)
 
-                 }
 
-             }
 
-             str
 
-         }
 
-     };
 
-     (@internal $_p:ident.$($p:ident).*) => {
 
-         str_per!(@internal $($p).*)
 
-     };
 
- }
 
- macro_rules! bt_map {
 
-     ( $( ($k:expr, $v:expr) ),* $(,)?) => {
 
-         {
 
-             let mut map = std::collections::BTreeMap::new();
 
-             $(
 
-                 map.insert($k, $v)
 
-             )*
 
-             map
 
-         }
 
-     };
 
-     ($($k:expr),* $(,)?) => {
 
-         {
 
-             let mut map = std::collections::BTreeMap::new();
 
-             $(
 
-                 let entry: (_,_) = $k;
 
-                 map.insert(entry.0, entry.1);
 
-             )*
 
-             map
 
-         }
 
-     }
 
- }
 
- impl PubReqHead {
 
-     pub fn encrypt_sign<T>(&mut self, config: &Config, data: T) -> anyhow::Result<()>
 
-     where
 
-         T: serde::Serialize,
 
-     {
 
-         let data = serde_json::to_string(&data)?;
 
-         let key = config
 
-             .sd_config
 
-             .get_pk()
 
-             .context("PayReqHead::encrypt_sign")?;
 
-         let r = key.encrypt(data, gmssl::sm2::PassOrder::C1C3C2)?;
 
-         let data = hex::encode(r);
 
-         self.biz_content = data;
 
-         self.sign(config);
 
-         Ok(())
 
-     }
 
-     pub fn decopy<T>(&self, config: &Config) -> anyhow::Result<T>
 
-     where
 
-         T: for<'a> serde::Deserialize<'a>,
 
-     {
 
-         let key = config.sd_config.get_sk().context("PayReqHead::decopy")?;
 
-         let data = hex::decode(&self.biz_content).context("hex::decode Error")?;
 
-         let s = key
 
-             .decrypt(data, gmssl::sm2::PassOrder::C1C3C2)
 
-             .context("解密 biz_content")?;
 
-         serde_json::from_slice(&s).context("反序列化 biz_content")
 
-     }
 
-     fn sign(&mut self, config: &Config) {
 
-         self.sign = hex::encode_upper(self.sign_var(config))
 
-     }
 
-     pub fn sign_var(&self, config: &Config) -> Vec<u8> {
 
-         let mut aa = Md5::new();
 
-         let s = self.format_str(config);
 
-         aa.update(s);
 
-         let r = aa.finalize().to_vec();
 
-         tracing::debug!("{self:?} Sing:{}", hex::encode(&r));
 
-         r
 
-     }
 
-     pub fn format_str(&self, config: &Config) -> String {
 
-         let Self {
 
-             app_id,
 
-             method,
 
-             sign_type,
 
-             sign,
 
-             timestamp,
 
-             version,
 
-             request_id,
 
-             biz_content,
 
-         } = self;
 
-         let map = bt_map!(
 
-             str_per!(app_id),
 
-             str_per!(method),
 
-             str_per!(sign_type),
 
-             str_per!(sign),
 
-             str_per!(timestamp),
 
-             str_per!(version),
 
-             str_per!(request_id),
 
-             str_per!(biz_content)
 
-         );
 
-         let items: Vec<_> = map
 
-             .into_iter()
 
-             .map(|(k, v)| (k.trim().to_owned(), v.trim().to_owned()))
 
-             .filter(|(k, v)| !v.is_empty() && k != "sign")
 
-             .map(|(k, v)| format!("{}={}", k, v))
 
-             .collect();
 
-         let mut result = items.join("&");
 
-         result.push('&');
 
-         result.push_str(&format!("key={}", config.sd_config.sin_key));
 
-         result
 
-     }
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct PayReqBody {
 
-     pub game_user_id: String,
 
-     pub server_type: String,
 
-     pub product_no: String,
 
-     pub sp_order_id: String,
 
-     pub source: String,
 
- }
 
- impl crate::Verify for PayReqBody {
 
-     fn verify(&self, _: &Config) -> anyhow::Result<()> {
 
-         if self.server_type != "tel" {
 
-             return Err(anyhow::Error::msg("仅支持话费"));
 
-         }
 
-         Ok(())
 
-     }
 
- }
 
- impl PayReqBody {
 
-     pub fn into_backend_pay_req(
 
-         &self,
 
-         head: &PubReqHead,
 
-         config: &Config,
 
-     ) -> backend::Body<backend::PayReqBody> {
 
-         let timestamp = head.timestamp.trim().replace(
 
-             |c: char| c.is_whitespace() || c == '-' || c == '_' || c == ':',
 
-             "",
 
-         );
 
-         let mut body = backend::Body {
 
-             header: backend::Header {
 
-                 timestamp,
 
-                 seqno: head.request_id.clone(),
 
-                 appid: config.fscg_config.app_id.clone(),
 
-                 ..Default::default()
 
-             },
 
-             msgbody: backend::PayReqBody {
 
-                 content: Some(backend::PayReqContent {
 
-                     user: self.game_user_id.clone(),
 
-                     packageid: self.product_no.clone(),
 
-                     extorder: self.sp_order_id.clone(),
 
-                     note: Some(self.source.clone()),
 
-                     ..Default::default()
 
-                 }),
 
-                 resp: None,
 
-             },
 
-         };
 
-         body.sign(config);
 
-         body
 
-     }
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct PayRespBodyData {
 
-     state: String,
 
-     order_cash: String,
 
-     order_id: String,
 
-     sp_order_id: String,
 
-     game_user_id: String,
 
-     product_name: String,
 
- }
 
- pub type PayRespBody = PubRespBody<PayRespBodyData>;
 
- impl PayRespBody {
 
-     pub fn from_backend_pay_resp(
 
-         config: &Config,
 
-         body: backend::Body<backend::PayRespBody>,
 
-         req: &PayReqBody,
 
-     ) -> Self {
 
-         if let Err(e) = body.verify(config) {
 
-             // return Self::error("99", "服务响应验证错误");
 
-             return Self::error("99", format!("服务响应验证错误: {:#?}", e));
 
-         }
 
-         let resp = match body.msgbody.resp {
 
-             Some(resp) => resp,
 
-             None => {
 
-                 return Self::error("99", "服务没有响应字段: resp");
 
-             }
 
-         };
 
-         let content = match body.msgbody.content {
 
-             Some(content) => content,
 
-             None => {
 
-                 return Self::error(
 
-                     resp.rcode,
 
-                     resp.rmsg.unwrap_or("服务没有响应字段: content".to_string()),
 
-                 );
 
-             }
 
-         };
 
-         let state = if resp.rcode == "00" {
 
-             "0".to_string()
 
-         } else {
 
-             "9".to_string()
 
-         };
 
-         Self::success(PayRespBodyData {
 
-             state,
 
-             order_cash: "".to_string(),
 
-             order_id: content.orderid,
 
-             sp_order_id: content.extorder,
 
-             game_user_id: req.game_user_id.clone(),
 
-             product_name: req.product_no.clone(),
 
-         })
 
-     }
 
- }
 
- impl crate::Sign for PayRespBody {
 
-     fn sign(&mut self, _: &Config) {}
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct BalanceRespBody {
 
-     pub result_code: String,
 
-     pub result_desc: String,
 
-     pub balance: Option<String>,
 
- }
 
- impl BalanceRespBody {
 
-     pub fn from_backend_account_resp(
 
-         config: &Config,
 
-         body: backend::Body<backend::AccountRespBody>,
 
-     ) -> Self {
 
-         if let Err(e) = body.verify(config) {
 
-             return Self::error("99", format!("服务响应验证错误: {:#?}", e));
 
-         }
 
-         let resp = match body.msgbody.resp {
 
-             Some(resp) => resp,
 
-             None => {
 
-                 return Self::error("99", "服务没有响应字段: resp");
 
-             }
 
-         };
 
-         let content = match body.msgbody.content {
 
-             Some(content) => content,
 
-             None => {
 
-                 return Self::error(
 
-                     resp.rcode,
 
-                     resp.rmsg.unwrap_or("服务没有响应字段: content".to_string()),
 
-                 );
 
-             }
 
-         };
 
-         Self::success(content.balance)
 
-     }
 
-     pub fn success(data: impl Into<Option<String>>) -> Self {
 
-         Self {
 
-             result_code: "000".to_string(),
 
-             result_desc: "success".to_string(),
 
-             balance: data.into(),
 
-         }
 
-     }
 
-     pub fn error(code: impl ToString, desc: impl ToString) -> Self {
 
-         Self {
 
-             result_code: code.to_string(),
 
-             result_desc: desc.to_string(),
 
-             balance: None,
 
-         }
 
-     }
 
- }
 
- impl crate::Sign for BalanceRespBody {
 
-     fn sign(&mut self, _: &Config) {}
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct BalanceReqBody {
 
-     source: String,
 
- }
 
- impl BalanceReqBody {
 
-     pub fn into_backend_account_req(
 
-         &self,
 
-         config: &Config,
 
-         head: &PubReqHead,
 
-     ) -> backend::Body<backend::AccountReqBody> {
 
-         let backend_req = backend::AccountReqBody::new();
 
-         let mut body = backend::Body {
 
-             header: backend::Header {
 
-                 seqno: head.request_id.clone(),
 
-                 appid: config.fscg_config.app_id.clone(),
 
-                 ..Default::default()
 
-             },
 
-             msgbody: backend_req,
 
-         };
 
-         body.sign(config);
 
-         body
 
-     }
 
- }
 
- impl crate::Verify for BalanceReqBody {
 
-     fn verify(&self, _: &Config) -> anyhow::Result<()> {
 
-         if self.source == "SD" {
 
-             Ok(())
 
-         } else {
 
-             Err(anyhow::Error::msg("BalanceReqBody Verify False"))
 
-         }
 
-     }
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct SearchReqBody {
 
-     sp_order_id: String,
 
- }
 
- impl SearchReqBody {
 
-     pub fn into_backend_search_req(
 
-         &self,
 
-         head: &PubReqHead,
 
-         config: &Config,
 
-     ) -> backend::Body<backend::SearchReqBody> {
 
-         let mut body = backend::Body {
 
-             header: backend::Header {
 
-                 seqno: head.request_id.clone(),
 
-                 appid: config.fscg_config.app_id.clone(),
 
-                 ..Default::default()
 
-             },
 
-             msgbody: backend::SearchReqBody {
 
-                 content: Some(backend::SearchReqContent {
 
-                     // orderid: Some(req.sp_order_id.clone()),
 
-                     extorderid: Some(self.sp_order_id.clone()),
 
-                     ..Default::default()
 
-                 }),
 
-                 resp: None,
 
-             },
 
-         };
 
-         body.sign(config);
 
-         body
 
-     }
 
- }
 
- impl crate::Verify for SearchReqBody {}
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct SearchRespData {
 
-     state: String,
 
-     message: String,
 
-     success_time: Option<String>,
 
-     order_id: String,
 
-     sp_order_id: String,
 
-     game_user_id: String,
 
-     operator_order: Option<String>,
 
-     card_no: Option<String>,        // 卡密
 
-     card_pwd: Option<String>,       // 卡密
 
-     effective_time: Option<String>, // 卡密
 
- }
 
- pub type SearchRespBody = PubRespBody<SearchRespData>;
 
- impl SearchRespBody {
 
-     pub fn from_backend_search_resp(
 
-         config: &Config,
 
-         body: backend::Body<backend::SearchRespBody>,
 
-     ) -> Self {
 
-         if let Err(e) = body.verify(config) {
 
-             Self::error("99", format!("服务响应验证错误: {:#?}", e));
 
-         }
 
-         let resp = match body.msgbody.resp {
 
-             Some(resp) => resp,
 
-             None => {
 
-                 return Self::error("99", "服务没有响应字段: resp".to_string());
 
-             }
 
-         };
 
-         let content = match body.msgbody.content {
 
-             Some(content) => content,
 
-             None => {
 
-                 return Self::error(
 
-                     resp.rcode,
 
-                     resp.rmsg.unwrap_or("服务没有响应字段: content".to_string()),
 
-                 );
 
-             }
 
-         };
 
-         let state = if content.status == "6" {
 
-             "1"
 
-         } else if content.status == "4" {
 
-             "9"
 
-         } else {
 
-             "0"
 
-         };
 
-         let time_str = if content.checktime.is_empty() {
 
-             None
 
-         } else {
 
-             let time_format = time::macros::format_description!("[year]-[month padding:zero]-[day padding:zero] [hour padding:zero]:[minute padding:zero]:[second padding:zero]");
 
-             let backend_time = time::macros::format_description!("[year][month padding:zero][day padding:zero][hour padding:zero][minute padding:zero][second padding:zero][subsecond digits:1+]");
 
-             let time = time::PrimitiveDateTime::parse(&content.checktime, backend_time).unwrap();
 
-             let time_str = time.format(time_format).unwrap();
 
-             Some(time_str)
 
-         };
 
-         let data = SearchRespData {
 
-             state: state.to_string(),
 
-             message: content.msg,
 
-             success_time: time_str,
 
-             order_id: content.orderid,
 
-             sp_order_id: content.extorder,
 
-             game_user_id: content.user,
 
-             operator_order: content.attr1,
 
-             card_no: None,
 
-             card_pwd: None,
 
-             effective_time: None,
 
-         };
 
-         Self::success(data)
 
-     }
 
- }
 
- impl crate::Sign for SearchRespBody {
 
-     fn sign(&mut self, _: &Config) {}
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct PubRespBody<T> {
 
-     pub result_code: String,
 
-     pub result_desc: String,
 
-     pub data: Option<T>,
 
- }
 
- impl<T> PubRespBody<T> {
 
-     pub fn success(data: T) -> Self {
 
-         Self {
 
-             result_code: "000".to_string(),
 
-             result_desc: "success".to_string(),
 
-             data: Some(data),
 
-         }
 
-     }
 
-     pub fn error(code: impl ToString, desc: impl ToString) -> Self {
 
-         Self {
 
-             result_code: code.to_string(),
 
-             result_desc: desc.to_string(),
 
-             data: None,
 
-         }
 
-     }
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct PubRespHead {
 
-     #[serde(default = "String::new")]
 
-     pub code: String,
 
-     #[serde(default = "String::new")]
 
-     pub msg: String,
 
-     #[serde(default = "String::new")]
 
-     pub data: String,
 
-     #[serde(default = "String::new")]
 
-     pub sign: String,
 
-     #[serde(default = "String::new")]
 
-     pub request_id: String,
 
- }
 
- impl IntoResponse for PubRespHead {
 
-     fn into_response(self) -> axum::response::Response {
 
-         Json(self).into_response()
 
-     }
 
- }
 
- impl PubRespHead {
 
-     pub fn new(config: &Config, data: impl ToString, request_id: impl ToString) -> Self {
 
-         let mut result = Self {
 
-             data: data.to_string(),
 
-             request_id: request_id.to_string(),
 
-             ..Default::default()
 
-         };
 
-         result.sign(config);
 
-         result
 
-     }
 
-     pub fn sign(&mut self, config: &Config) {
 
-         self.sign = hex::encode_upper(self.sign_var(config))
 
-     }
 
-     pub fn sign_var(&self, config: &Config) -> Vec<u8> {
 
-         let mut aa = Md5::new();
 
-         let s = self.format_str(config);
 
-         aa.update(&s);
 
-         let r = aa.finalize().to_vec();
 
-         tracing::debug!(sign = hex::encode(&r), data = s, "签名");
 
-         r
 
-     }
 
-     pub fn format_str(&self, config: &Config) -> String {
 
-         let Self {
 
-             code,
 
-             msg,
 
-             data,
 
-             sign,
 
-             request_id,
 
-         } = self;
 
-         let map = bt_map!(
 
-             str_per!(code),
 
-             str_per!(msg),
 
-             str_per!(data),
 
-             str_per!(sign),
 
-             str_per!(request_id),
 
-         );
 
-         let items: Vec<_> = map
 
-             .into_iter()
 
-             .map(|(k, v)| (k.trim().to_owned(), v.trim().to_owned()))
 
-             .filter(|(k, v)| !v.is_empty() && k != "sign")
 
-             .map(|(k, v)| format!("{}={}", k, v))
 
-             .collect();
 
-         let mut result = items.join("&");
 
-         result.push('&');
 
-         result.push_str(&format!("key={}", config.sd_config.sin_key));
 
-         result
 
-     }
 
- }
 
- impl Default for PubRespHead {
 
-     fn default() -> Self {
 
-         Self {
 
-             code: "000".to_string(),
 
-             msg: "success".to_string(),
 
-             data: "".to_string(),
 
-             sign: "".to_string(),
 
-             request_id: "".to_string(),
 
-         }
 
-     }
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct CallbackReqBody {
 
-     pub state: String,
 
-     pub message: String,
 
-     pub order_id: String,
 
-     pub sp_order_id: String,
 
-     pub game_user_id: String,
 
-     pub operator_order: Option<String>,
 
-     pub card_no: Option<String>,
 
-     pub card_pwd: Option<String>,
 
-     pub effective_time: Option<String>,
 
- }
 
- impl Default for CallbackReqBody {
 
-     fn default() -> Self {
 
-         Self {
 
-             state: "".to_string(),
 
-             message: "".to_string(),
 
-             order_id: "".to_string(),
 
-             sp_order_id: "".to_string(),
 
-             game_user_id: "".to_string(),
 
-             operator_order: None,
 
-             card_no: None,
 
-             card_pwd: None,
 
-             effective_time: None,
 
-         }
 
-     }
 
- }
 
- #[derive(serde::Serialize, serde::Deserialize, Debug)]
 
- #[serde(rename_all = "camelCase")]
 
- pub struct CallbackRespBody {
 
-     pub result_code: String,
 
-     pub result_desc: String,
 
- }
 
- #[cfg(test)]
 
- #[allow(unused)]
 
- mod tests {
 
-     use crate::config::SdConfig;
 
-     use super::*;
 
-     #[test]
 
-     fn test_aaaa() {
 
-         let s = "04f97e835ec530a95df4c999ab0184996b68464bf308239ebb692174812fb4c54349fc217ac5ab13ea8313e458e2cf37fa35345afc4290f8d25dc7c8bb37da1a0ff87a7752c8d03998067b3bf9fec1d7e397aba05fb016b3b48e269e9c87c22b6eef61508de4572c7dacd980530dac913f507ad9aa2a2a8c62edae35c21bf3aaa446168989a1350914499322ebb5b37038e432ed8f37e25083e35087b4fc1dbff3488c1e7cd7810712725a1fd78365a73892bf6b45352ca775b7b2e66a334ed93986728d2c2c78af2bbfaeb590d55a494163371c0c5df7";
 
-         let head =  PubReqHead{biz_content: s.to_string(), ..Default::default()};
 
-         let cfg = Config::default();
 
-         let r = head.decopy::<serde_json::Value>(&cfg);
 
-         println!("{:#?}", r)
 
-     }
 
-     #[test]
 
-     fn test_sign() {
 
-         // 2C5A4C48A9BD07B79C250049A17C21C2
 
-         // 2C5A4C48A9BD07B79C250049A17C21C2
 
-         let mut a = PubReqHead {
 
-             app_id: "asdaw".to_string(),
 
-             method: "asdaw".to_string(),
 
-             sign_type: "asdaw".to_string(),
 
-             sign: "asdaw".to_string(),
 
-             timestamp: "2023-03-23 16:25:00".to_string(),
 
-             version: "asdaw".to_string(),
 
-             request_id: "asdaw".to_string(),
 
-             biz_content: "".to_string(),
 
-         };
 
-         let c = Default::default();
 
-         a.sign(&c);
 
-         println!("{a:?}");
 
-     }
 
-     #[test]
 
-     fn feature() {
 
-         let r = PayReqBody {
 
-             game_user_id: "13856023633".to_string(),
 
-             server_type: "tel".to_string(),
 
-             product_no: "LD_5477".to_string(),
 
-             sp_order_id: "QHGHFBGF0235641202".to_string(),
 
-             source: "SD".to_string(),
 
-         };
 
-         let r = serde_json::to_string(&r).unwrap();
 
-         println!("{r}")
 
-     }
 
-     #[test]
 
-     fn test_try_into_fscg_req() {
 
-         // 470EF517335D444BD003098D6F6ABCE0
 
-         // 470EF517335D444BD003098D6F6ABCE0
 
-         let now = std::time::Instant::now();
 
-         let mut a = PubReqHead {
 
-             app_id: "asdaw".to_string(),
 
-             method: "asdaw".to_string(),
 
-             sign_type: "asdaw".to_string(),
 
-             sign: "asdaw".to_string(),
 
-             timestamp: "2023-03-23 16:25:00".to_string(),
 
-             version: "asdaw".to_string(),
 
-             request_id: "asdaw".to_string(),
 
-             biz_content: r#"{"gameUserId":"13856023633","serverType":"tel","productNo":"LD_5477","spOrderId":"QHGHFBGF0235641202","source":"SD"}"#.to_string(),
 
-         };
 
-         let c: Config = Default::default();
 
-         // let r = c.sd_config.;
 
-         let key = c.sd_config.get_sk().unwrap();
 
-         let r = key
 
-             .encrypt(a.biz_content, gmssl::sm2::PassOrder::C1C2C3)
 
-             .unwrap();
 
-         a.biz_content = hex::encode(r);
 
-         a.sign(&c);
 
-         println!("{a:?}");
 
-         let new = std::time::Instant::now();
 
-         println!("use Time{:?}", new - now);
 
-     }
 
- }
 
 
  |