From 790c16cfec16d858d5da47afb4f68e94636d3250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BD=98=E5=AE=89?= Date: Sun, 16 Nov 2025 19:24:30 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 5 +- src/alipay/mod.rs | 2 +- src/alipay/request/mod.rs | 8 +- src/errors.rs | 5 + src/qiniu/mod.rs | 90 ++++++++++++- src/session.rs | 11 +- src/util/md5.rs | 5 +- src/util/prp.rs | 172 ++++++++++++++++++++----- src/wechat/cp/api/agent.rs | 2 +- src/wechat/cp/api/codesession.rs | 2 +- src/wechat/cp/api/department.rs | 2 +- src/wechat/cp/api/external_contact.rs | 10 +- src/wechat/cp/api/group_robot.rs | 14 +- src/wechat/cp/api/media.rs | 2 +- src/wechat/cp/api/menu.rs | 2 +- src/wechat/cp/api/message.rs | 6 +- src/wechat/cp/api/oauth2.rs | 2 +- src/wechat/cp/api/tag.rs | 6 +- src/wechat/cp/api/user.rs | 2 +- src/wechat/cp/events/contact_change.rs | 18 +-- src/wechat/cp/mod.rs | 26 ++-- src/wechat/cp/tp/agent.rs | 2 +- src/wechat/cp/tp/auth.rs | 2 +- src/wechat/cp/tp/department.rs | 2 +- src/wechat/cp/tp/license.rs | 2 +- src/wechat/cp/tp/media.rs | 2 +- src/wechat/cp/tp/mod.rs | 26 ++-- src/wechat/cp/tp/order.rs | 2 +- src/wechat/cp/tp/tag.rs | 2 +- src/wechat/cp/tp/user.rs | 8 +- src/wechat/cryptos/mod.rs | 1 + src/wechat/miniapp/api/codesession.rs | 2 +- src/wechat/miniapp/api/media.rs | 2 +- src/wechat/miniapp/api/message.rs | 2 +- src/wechat/miniapp/api/qrcode.rs | 2 +- src/wechat/miniapp/api/user.rs | 2 +- src/wechat/miniapp/mod.rs | 10 +- src/wechat/mp/api/card.rs | 2 +- src/wechat/mp/api/customservice.rs | 2 +- src/wechat/mp/api/media.rs | 2 +- src/wechat/mp/api/member.rs | 10 +- src/wechat/mp/api/menu.rs | 2 +- src/wechat/mp/api/oauth2.rs | 2 +- src/wechat/mp/api/ocr.rs | 2 +- src/wechat/mp/api/qrcode.rs | 6 +- src/wechat/mp/api/subscribe_msg.rs | 2 +- src/wechat/mp/api/template_msg.rs | 2 +- src/wechat/mp/api/user.rs | 2 +- src/wechat/mp/api/wifi.rs | 2 +- src/wechat/mp/mod.rs | 24 ++-- src/wechat/pay/api/wxpay.rs | 2 +- src/wechat/pay/mod.rs | 2 +- src/wechat/pay/request/mod.rs | 6 +- 53 files changed, 362 insertions(+), 169 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 40c7fd6..bf49202 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,13 +16,13 @@ license = "MIT" [dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -redis = { version = "0.21.0", features = ["r2d2"]} +redis = { version = "0.23.1", features = ["r2d2","streams"] } reqwest = { version = "0.11.0", features = ["blocking", "json","native-tls","__rustls", "native-tls-crate", "multipart"] } bytes = { version = "1.1.0", features = ["serde"] } r2d2 = {version = "0.8.9"} chrono = { version = "0.4", features = ["serde"]} - +time = "0.3.26" rand = "0.7.3" uuid = { version = "0.7.4", features = ["serde", "v4"] } byteorder = {version = "1.3.4"} @@ -45,6 +45,7 @@ sha2 = { version = "0.10" } hmac = { version = "0.12" } hex = { version = "0.4.3" } aes = { version = "0.7.5" } +cfb-mode = "0.7" aes-gcm = { version = "0.10" } base64 = "0.12" bincode = "1.3.3" diff --git a/src/alipay/mod.rs b/src/alipay/mod.rs index bbcfb5f..7433711 100644 --- a/src/alipay/mod.rs +++ b/src/alipay/mod.rs @@ -580,7 +580,7 @@ impl AlipayClient { } let key = self.encrypt_key.to_owned().unwrap_or_default(); let prp = PrpCrypto::new(key.into_bytes()); - let encrypt_content = prp.aes_128_cbc_encrypt_data(biz_content, Some(&get_nonce_str()))?; + let encrypt_content = prp.aes_128_cbc_encrypt_data(biz_content, Some(get_nonce_str().into_bytes()))?; let encrypt_content = String::from_utf8_lossy(&encrypt_content).to_string(); app_params.insert(constants::BIZ_CONTENT_KEY.to_string(), encrypt_content); } diff --git a/src/alipay/request/mod.rs b/src/alipay/request/mod.rs index 3ef9deb..c8a0502 100644 --- a/src/alipay/request/mod.rs +++ b/src/alipay/request/mod.rs @@ -605,7 +605,7 @@ pub struct AlipayTradePayModel { /// 结算信息、 /// json格式,详见结算参数说明。 /// 直付通模式下必传。 - pub settle_info: Option, + pub settle_info: Option, /// 二级商户信息。 /// 直付通模式和机构间连模式下必传,其它场景下不需要传入。。 pub sub_merchant: Option, @@ -934,7 +934,7 @@ pub struct AlipayTradePrecreateModel { /// 结算信息、 /// json格式,详见结算参数说明。 /// 直付通模式下必传。 - pub settle_info: Option, + pub settle_info: Option, /// 订单包含的商品列表信息,json格式,其它说明详见商品明细说明 pub goods_detail: Option, /// 业务扩展参数 @@ -1134,7 +1134,7 @@ pub struct AlipayTradeCreateModel { /// 结算信息、 /// json格式,详见结算参数说明。 /// 直付通模式下必传。 - pub settle_info: Option, + pub settle_info: Option, /// 订单包含的商品列表信息,json格式,其它说明详见商品明细说明 pub goods_detail: Option, /// 业务扩展参数 @@ -1304,7 +1304,7 @@ pub struct PromoParam { /// 外部指定买家 #[derive(Debug, Serialize, Deserialize)] -pub struct SettleInfo { +pub struct AlipaySettleInfo { /// 结算详细信息,json数组,目前只支持一条。 pub settle_detail_infos: Option>, /// 该笔订单的超期自动确认结算时间,到达期限后,将自动确认结算。此字段只在签约账期结算模式时有效。取值范围:1d~365d。d-天。 该参数数值不接受小数点。 diff --git a/src/errors.rs b/src/errors.rs index c762e9a..64f2ef4 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -164,6 +164,11 @@ impl From for LabraError { LabraError::InvalidSignature(format!("字符编码出错:{}", err.to_string())) } } +impl From for LabraError { + fn from(err: cfb_mode::cipher::errors::InvalidLength) -> Self { + LabraError::InvalidSignature(format!("InvalidLength:{}", err.to_string())) + } +} impl From for LabraError { fn from(err: r2d2::Error) -> Self { LabraError::RequestError(format!("redis连接错误:{}", err.to_string())) diff --git a/src/qiniu/mod.rs b/src/qiniu/mod.rs index 1ad2ae8..4bc8b68 100644 --- a/src/qiniu/mod.rs +++ b/src/qiniu/mod.rs @@ -70,7 +70,7 @@ impl<'a> Qiniu<'a> { } - pub fn get_access_token(&self, filename: &str) -> String { + pub fn get_upload_token(&self, filename: &str) -> String { // 1.构造上传策略 // let setting = &SETTINGS; let bucket_name = self.bucket.to_owned(); @@ -97,6 +97,47 @@ impl<'a> Qiniu<'a> { data } + + pub fn get_access_token(&self, method: &str, req_url: &str, req_content_type: Option<&str>, req_keys: Option>, req_body: Option<&str>) -> String { + let secret_key = self.secret_key.to_owned(); + let access_key = self.access_key.to_owned(); + + let mut signing_str = format!("{} {}\nHost: ", method.to_uppercase(), req_url); + if let Some(content_type) = req_content_type { + signing_str.push_str("\n"); + signing_str.push_str("Content-Type: "); + signing_str.push_str(content_type); + } + if let Some(req_keys) = req_keys { + for (k, v) in req_keys.iter() { + signing_str.push_str("\n"); + signing_str.push_str(k); + signing_str.push_str(": "); + signing_str.push_str(v); + } + } + + signing_str.push_str("\n"); + signing_str.push_str("\n"); + + if let Some(body) = req_body { + let content_type = req_content_type.unwrap_or_default(); + if !content_type.contains("application/octet-stream") { + signing_str.push_str(body); + } + + } + debug!("七牛云管理凭证待签名字符串: {}", &signing_str); + // 使用访问密钥(AK/SK)对上一步生成的待签名字符串计算HMAC-SHA1签名 + let prp = PrpCrypto::new(secret_key.as_bytes().to_vec()); + let result = prp.hmac_sha1_sign(&signing_str).unwrap_or_default(); + // 对签名进行URL安全的Base64编码 + let encoded_sign = safe_base64(result);//base64::encode(result.code()); + let data = format!("{}:{}",access_key, encoded_sign); + debug!("七牛云管理凭证: {}", &data); + data + } + pub fn host(&self, bucket: &str, object: &str, resources_str: &str) -> String { if self.endpoint.starts_with("https") { format!( @@ -118,7 +159,7 @@ impl<'a> Qiniu<'a> { } pub async fn upload(&self, file: Bytes, filename: String) -> LabradorResult { - let upload_token = self.get_access_token(filename.as_str()); + let upload_token = self.get_upload_token(filename.as_str()); let mut headers = HeaderMap::new(); headers.insert("Host", "up-z2.qiniup.com".parse().unwrap()); let client = reqwest::Client::new(); @@ -138,6 +179,51 @@ impl<'a> Qiniu<'a> { Ok(result) } + pub async fn delete_obj(&self, obj_name: String) -> LabradorResult { + let mut headers = HeaderMap::new(); + headers.insert("Host", "rs.qiniup.com".parse().unwrap()); + headers.insert("Content-Type", "application/x-www-form-urlencoded".parse().unwrap()); + let client = reqwest::Client::new(); + let entry = format!("{}:{}", self.bucket(), &obj_name); + let encoded_entry_uri = safe_base64(entry); + let url = format!("/delete/{}", encoded_entry_uri); + let token = self.get_access_token("POST", &url, Some("application/x-www-form-urlencoded"), None, None); + headers.insert("Authorization", format!("Qiniu {}", token).parse().unwrap()); + let result = client + .post(format!("{}{}", self.endpoint(), url)) + .form(&serde_json::Value::Null) + .headers(headers.to_owned()).send().await.map_err(|err| LabraError::ApiError(err.to_string()))? + .text().await.map_err(|err| LabraError::ApiError(err.to_string()))?; + Ok(result) + } + + pub async fn get_obj(&self, obj_name: &str) -> LabradorResult { + let domains = self.domains().await?; + let domain = domains.first().map(ToString::to_string).unwrap_or_default(); + let client = reqwest::Client::new(); + let result = client + .get(format!("{}/{}", domain, obj_name)).send().await.map_err(|err| LabraError::ApiError(err.to_string()))? + .bytes().await.map_err(|err| LabraError::ApiError(err.to_string()))?; + Ok(result) + } + + pub async fn domains(&self) -> LabradorResult> { + let bucket = self.bucket.to_string(); + let mut headers = HeaderMap::new(); + headers.insert("Content-Type", "application/x-www-form-urlencoded".parse().unwrap()); + headers.insert("Host", "rs.qiniup.com".parse().unwrap()); + let client = reqwest::Client::new(); + let url = format!("/v2/domains?tbl={}", bucket); + let token = self.get_access_token("POST", &url, Some("application/x-www-form-urlencoded"), None, None); + headers.insert("Authorization", format!("Qiniu {}", token).parse().unwrap()); + let result = client + .post(format!("{}{}", self.endpoint(), url)) + .form(&serde_json::Value::Null) + .headers(headers.to_owned()).send().await.map_err(|err| LabraError::ApiError(err.to_string()))? + .json::>().await.map_err(|err| LabraError::ApiError(err.to_string()))?; + Ok(result) + } + } diff --git a/src/session.rs b/src/session.rs index 17a6f2a..91fb9fb 100644 --- a/src/session.rs +++ b/src/session.rs @@ -436,7 +436,7 @@ pub mod redis_store { } } - fn get_connect(&self) -> RedisPool { + pub fn get_connect(&self) -> RedisPool { let pool = self.client_pool.to_owned(); pool } @@ -448,8 +448,7 @@ pub mod redis_store { if !client.check_connection() { return Err(LabraError::ApiError("error to get redis connection".to_string())) } - let s = client.del(key.as_ref())?; - Ok(()) + client.del(key.as_ref()).map_err(LabraError::from) } pub fn zlcount, M: ToRedisArgs, MM: ToRedisArgs, RV: FromRedisValue>(&self, key: K, min: M, max: MM) -> LabradorResult { @@ -888,12 +887,10 @@ pub mod redis_store { return Err(LabraError::ApiError("error to get redis connection".to_string())) } if let Some(seconds) = ttl { - let _ = client.set_ex(key, value.to_store(), seconds)?; + client.set_ex(key, value.to_store(), seconds).map_err(LabraError::from) } else { - let _ = client.set(key, value.to_store())?; + client.set(key, value.to_store()).map_err(LabraError::from) } - - Ok(()) } } } diff --git a/src/util/md5.rs b/src/util/md5.rs index 226eef6..d1fda3d 100644 --- a/src/util/md5.rs +++ b/src/util/md5.rs @@ -1,8 +1,8 @@ -//! +//! //! MD5加密类 //! -use std::ops::Deref; + #[allow(unused)] static SALT: &'static str = "labrador"; @@ -28,6 +28,7 @@ pub fn md5>(input: S) -> String { #[cfg(not(feature = "openssl-crypto"))] fn crypto_md5(input: String) -> String { + use std::ops::Deref; let mut input_salt: String = String::new(); input_salt.push_str(input.as_str()); let result = md5::compute(input_salt.as_bytes()); diff --git a/src/util/prp.rs b/src/util/prp.rs index ade2e46..fa40f2e 100644 --- a/src/util/prp.rs +++ b/src/util/prp.rs @@ -5,16 +5,7 @@ use base64; use std::iter::repeat; - -use aes::cipher::{ - generic_array::GenericArray, -}; -use aes_gcm::AeadInPlace; -use block_modes::{BlockMode, Cbc, Ecb}; -use hmac::Mac; -use sha1::Digest; - -use crate::{cfg_if, LabradorResult}; +use crate::{cfg_if, LabraError, LabradorResult}; cfg_if! {if #[cfg(feature = "openssl-crypto")]{ use openssl::hash::{MessageDigest}; @@ -29,6 +20,13 @@ cfg_if! {if #[cfg(not(feature = "openssl-crypto"))]{ use rsa::pkcs8::DecodePrivateKey; use rsa::pkcs8::DecodePublicKey; use rsa::PublicKey; + use aes::cipher::{ + generic_array::GenericArray, + }; + use aes_gcm::AeadInPlace; + use block_modes::{BlockMode, Cbc, Ecb, Cfb}; + use hmac::Mac; + use sha1::Digest; }} #[allow(unused)] @@ -37,7 +35,7 @@ pub enum HashType { Sha256 } -#[derive(Debug, Eq, PartialEq)] +#[derive(Debug, Eq, PartialEq,Clone)] pub struct PrpCrypto { key: Vec, } @@ -62,12 +60,12 @@ impl PrpCrypto { } /// # 加密消息(aes_128_cbc) - pub fn aes_128_cbc_encrypt_data(&self, plaintext: &str, iv_data: Option<&str>) -> LabradorResult> { + pub fn aes_128_cbc_encrypt_data(&self, plaintext: &str, iv_data: Option>) -> LabradorResult> { let wtr = plaintext.as_bytes(); let key = &self.key; let mut iv = Vec::new(); if let Some(v) = iv_data { - iv = base64::decode(v)?; + iv = v; } else { iv = self.key[..16].to_vec(); } @@ -91,10 +89,10 @@ impl PrpCrypto { } /// # 解密消息(aes_128_cbc) - pub fn aes_128_cbc_decrypt_data(&self, ciphertext: Vec, iv_data: Option<&str>) -> LabradorResult> { + pub fn aes_128_cbc_decrypt_data(&self, ciphertext: Vec, iv_data: Option>) -> LabradorResult> { let mut iv = Vec::new(); if let Some(v) = iv_data { - iv = base64::decode(v)?; + iv = v; } else { iv = self.key[..16].to_vec(); } @@ -274,7 +272,6 @@ impl PrpCrypto { let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey)?; verifier.update(content)?; let ver = verifier.verify(sig)?; - println!("ver:{}", ver); Ok(ver) } @@ -346,6 +343,34 @@ impl PrpCrypto { sign(key, message) } + pub fn hmac_sha256_verify(&self, content: &str, sign: &str) -> LabradorResult { + let key = &self.key; + let sig = hex::decode(sign)?; + let content = content.as_bytes(); + + #[cfg(feature = "openssl-crypto")] + fn verify(sig: &[u8], key: &[u8], content: &[u8]) -> LabradorResult { + // 获取公钥对象 + let pkey = PKey::hmac(key)?; + // 对摘要进行签名 + let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey)?; + verifier.update(content)?; + let ver = verifier.verify(sig)?; + Ok(ver) + } + + #[cfg(not(feature = "openssl-crypto"))] + fn verify(sig: &[u8], key: &[u8], content: &[u8]) -> LabradorResult { + type HmacSha256 = hmac::Hmac; + + let mut mac = HmacSha256::new_from_slice(key)?; + mac.update(content); + let result = mac.verify_slice(sig).map_err(|err| crate::LabraError::RequestError(err.to_string()))?; + Ok(true) + } + verify(&sig, key, content) + } + pub fn hmac_sha1_sign(&self, message: &str) -> LabradorResult> { let key = &self.key; let message = message.as_bytes(); @@ -357,7 +382,6 @@ impl PrpCrypto { signer.update(message)?; let result = signer.sign_to_vec()?; Ok(result) - // Ok(result.to_hex()) } #[cfg(not(feature = "openssl-crypto"))] @@ -373,6 +397,32 @@ impl PrpCrypto { sign(key, message) } + pub fn hmac_sha1(&self, data: &[u8]) -> LabradorResult> { + let key = &self.key; + + #[cfg(feature = "openssl-crypto")] + fn sign(key: &[u8], message: &[u8]) -> LabradorResult> { + let pkey = PKey::hmac(key)?; + let mut signer = Signer::new(MessageDigest::sha1(), &pkey)?; + signer.update(message)?; + let result = signer.sign_to_vec()?; + Ok(result) + // Ok(result.to_hex()) + } + + #[cfg(not(feature = "openssl-crypto"))] + fn sign(key: &[u8], message: &[u8]) -> LabradorResult> { + type HmacSha1 = hmac::Hmac; + + let mut mac = HmacSha1::new_from_slice(key)?; + mac.update(message); + let result = mac.finalize(); + Ok(result.into_bytes().to_vec()) + } + + sign(key, data) + } + /// # 加密(aes_256_gcm) pub fn aes_256_gcm_encrypt(&self, associated_data: &[u8], nonce: &[u8], plain_text: &[u8]) -> LabradorResult> { @@ -467,6 +517,61 @@ impl PrpCrypto { let data = decrypt(key, data)?; Ok(String::from_utf8(data).unwrap_or_default()) } + + /// # 加密(aes_128_cfb) + pub fn aes_128_cfb_encrypt(&self, data: &[u8]) -> LabradorResult> { + if self.key.len() != 16 { + return Err(LabraError::InvalidSignature("AES-128 需要 16 字节的 key".to_string())); + } + let key = &self.key; + let iv = key; + + #[cfg(not(feature = "openssl-crypto"))] + fn encrypt(key: &[u8], iv: &[u8], data: &[u8]) -> LabradorResult> { + use cfb_mode::Cfb; + use cfb_mode::cipher::{NewCipher, AsyncStreamCipher}; + type AesCfb = Cfb; + let mut buffer = data.to_vec(); + AesCfb::new_from_slices(key, iv)?.encrypt(&mut buffer); + Ok(buffer) + } + + #[cfg(feature = "openssl-crypto")] + fn encrypt(key: &[u8], iv: &[u8], data: &[u8]) -> LabradorResult> { + let cipher = symm::Cipher::aes_128_cfb128(); + let encrypted = symm::encrypt(cipher, key, Some(iv), data)?; + Ok(encrypted) + } + + encrypt(key, iv, data) + } + + /// # 解密(aes_128_cfb) + pub fn aes_128_cfb_decrypt(&self, data: &[u8]) -> LabradorResult { + if self.key.len() != 16 { + return Err(LabraError::InvalidSignature("AES-128 需要 16 字节的 key".to_string())); + } + let key = &self.key; + let iv = key; + + #[cfg(feature = "openssl-crypto")] + fn decrypt(key: &[u8], iv: &[u8], data: &[u8]) -> LabradorResult> { + let cipher = symm::Cipher::aes_128_cfb128(); + let decrypted = symm::decrypt(cipher, key, Some(iv), data)?; + Ok(decrypted) + } + #[cfg(not(feature = "openssl-crypto"))] + fn decrypt(key: &[u8], iv: &[u8], data: &[u8]) -> LabradorResult> { + use cfb_mode::Cfb; + use cfb_mode::cipher::{NewCipher, AsyncStreamCipher}; + type AesCfb = Cfb; + let mut buffer = data.to_vec(); + AesCfb::new_from_slices(key, iv)?.decrypt(&mut buffer); + Ok(buffer) + } + let data = decrypt(key, iv, data)?; + Ok(String::from_utf8(data).unwrap_or_default()) + } } #[allow(unused, non_snake_case)] @@ -496,10 +601,6 @@ mod tests { // assert_eq!("test", &decrypted); } - fn hex_to_bytes(raw_hex: &str) -> Vec { - raw_hex.from_hex().ok().unwrap() - } - #[test] fn test_prpcrypto_decrypt_v3() { // let key = hex_to_bytes("feffe9928665731c6d6a8f9467308308"); @@ -526,9 +627,9 @@ mod tests { let iv= b"bb9ee5e44da1"; // let plain_text= hex_to_bytes("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39"); let cipher_text_base64=base64::decode("WZnvm4CnxNuPUYLIAh3Kv2WJFivwhLA2/xGxhwNHh5j2XmhUn2ibLm1I/pU3XKw6YWYLY8RfHsRHVcY4ln0NUUsiqsmgUxELKjqPKY0dWZSwXtbVAMlK+rGQbrgoopn/gNurM6Sx0jOjzorg091J0GGkxn2hHSaJ6EUtbHAGB3Nx/PTLr2o1rzNvF/QWLGE+5bcGe5Yg85qshvoGATJSwNAlVmdCOV4fg583irGzg6u7MYAytZpBoyzA4yf+9AKrO3K5lQwF5G6ULPWXtTNuW4rrC8wPI5xdnLqKopo9gNDUqg+19DYDSYsUvztRU7wORNh0SVkZLTwhOmKzFM8oqDHDuvcRCrUjw52NT85BQIFtsJMHciiFL+pefsz1llxlDnjroRyqNAyXw0RvKJfff40M8Fw7mAWK5eINQLPZAi4f9Ws7vC3WZ9/WGjrPOQInn8oLxzb8c+Wn0HSAxfEBRBmGx8FQ0+MdAP5bHTn3KCVxBM8gdx5vfeNqzcnRPG6qTMwuf/NE4BdnqNsDk5o3ZyhMGxnDfoJ+9PophG5KtdaPYHDVj/18PzT0w4GttSdw/1pisSPeOKcQqpI3/sC3ndDO7uqieUUAhMCtLxFCn1spndDLr+ciUs3CWJYlBgATE8vOFzPjVN8ECV+UeGULjkjWGBm0yPG3znbBpkX5Zvei4eZml16/JZHTWVgAKHpaaoBNH6qLKqS4UdpAXZJEQLAXflRw+4RjyD8ZsERcOTutnycozb/sPxB8N3qWhTGb8EJ8DTYSCILYemSIDmefmPU+ChzdM1FDbePMpHv8wCC/+zfRSwl0VtWXCauazZ3+1J9dW8ThvTOwlXPuRvOXFwCX/bq8BI3DX619TnahNBKU3+EfcvGGDO6bI5LvPSPLAaf1MgPc31Ab4jP+s73y4vc5IYNuwMC+aKuPmaxrqPA6Lr7PAUEicem4mYiTOAeG4hQh2C9XSOKrocsNDaOgLRiUU53bNY9sBTEkxoOc5prYVV7azwPfR506fSec0fv5c7v58srSK9zpTKNNVKbLL76WCpQ453dwmyaYeJNVqYoslzEL+kcb6UZVwr/Kj9TJka5bYHQOBmTRJT7FUeawvu4kHWzWnlRUShNFkuoymJEA8SXYyPliJgBWl36HAWse3PNr63K+RoYe8VdtviQQ02Js2Bg2RcTAlaxSoKuQdFfraGh35gVeJYEbrIp3N5goxLc6oc+bE/uoQI+pgv6oNsNznotp7bPCY1hIOEdtgvxMAUnpiU5ZsiPGt/N5KVAvSZJMzbuql3p2LBZjY3aGsNsT+xfgMj9K1fsORHP8/zt+RoF3AasSnn66zWRlxGlptkH+HtNxfEefaHtZ3NwYNPwaKwn9hIF5EotIhgLRsbEL9PWJLBVDuaWcmoaYDTNzAUlpGAKvyh2e4U7j3VuxPDiwNmPC+ZG/2CSMuD3+GPJodA3wbkhiNP4TAitKgYC03i94HDj8i2Th5HvNuA+dap7LaZerV7A34DwCK4rwk2C6z8+TAhdqagv2q1rnvzVT/dUXkIz3YMNkowboTpc/VgENPgUGBM4TtUpdk+hSxx/L5q/C+uWt8U1rIxbu5JrN3dHlvF/WfaCHQZP8e2QC8bz/TSX/tzFIQ6o/QtFWlF8OGbbndoNgTe5xyS5AwlprmR9FWFzjim8JAKNKMTKTrW3U6TKSUxSD9m7sl08rD3pCk+1kkKiVEgcuVHPd985n1xr4Ex9Hr8pJBTDcbkzis+dvh+CajqgsrYas+Eq8NTM8pz004PcPfZZzuaLgjl0Z+l7ZschSCkzq54BRxfIcvwywqJUhtRmB6xccpCtln6AsC/FS+kcJdAYEnnuU5uoPmNCcf3n+jDL9UGbcNg5Nj/w92tyF5A==").unwrap(); - let base64_cipher = cipher_text_base64.to_hex(); + let base64_cipher = "".to_string();// cipher_text_base64.to_hex(); println!("cipher_text:{}", &base64_cipher); - let cipher_text = hex_to_bytes(&base64_cipher); + let cipher_text = "".as_bytes().to_vec();//hex_to_bytes(&base64_cipher); let aad= b"certificate"; let cipherdata_length = cipher_text.len() - 16; @@ -576,18 +677,19 @@ mod tests { #[test] fn test_aes_128_ecb() { - let appId = "1ebc3d10ce15cf8cc601f60d3e84385c4d7acc9cc70fcd56dbbd969300c8f6082625cdd2cf66738f4635406a4c796bf7e1769d7ccfb468537ba211bdbf8fb13e09c343f52b1f5a47cab44126b61e338acc93b4cc12939a131f7b15a1af54be699dbb7ce3770aa8261af253d2aeac41c1c2db333d0052b48de4e58541bab56d98"; - let key = base64::decode("4ChT08phkz59hquD795X7w==").unwrap(); - let prp = PrpCrypto::new(key); - // println!("result:{}", prp.aes_128_cbc_decrypt_data(appId, "dsd2bb9ee5e44da1").unwrap()); - // match prp.decrypt_data(encryptedData, iv) { - // Ok(data) => { - // println!("data:{}",data); - // } - // Err(err) => { - // println!("err:{:?}",err); - // } - // } + let encryptedData = "KdT2tYR95PQU+U5ZxaQn+dyNjRMqfiy2ZEzIA5HkQrQ="; + let iv = base64::encode("1qaz2wsx3edc4rfv"); + let encryptedData = base64::decode(encryptedData).unwrap(); + let key = "1qaz2wsx3edc4rfv"; + let prp = PrpCrypto::new(key.as_bytes().to_owned().to_vec()); + match prp.aes_128_cbc_decrypt_data(encryptedData, Some(&iv)) { + Ok(data) => { + println!("data:{}",String::from_utf8_lossy(&data)); + } + Err(err) => { + println!("err:{:?}",err); + } + } } } diff --git a/src/wechat/cp/api/agent.rs b/src/wechat/cp/api/agent.rs index 27aceab..9ec63c3 100644 --- a/src/wechat/cp/api/agent.rs +++ b/src/wechat/cp/api/agent.rs @@ -14,7 +14,7 @@ pub struct WechatCpAgent<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpAgent<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpAgent { + pub fn new(client: &WechatCpClient) -> WechatCpAgent<'_, T> { WechatCpAgent { client, } diff --git a/src/wechat/cp/api/codesession.rs b/src/wechat/cp/api/codesession.rs index 0cda6f8..35a51e7 100644 --- a/src/wechat/cp/api/codesession.rs +++ b/src/wechat/cp/api/codesession.rs @@ -14,7 +14,7 @@ pub struct WechatCpCodeSession<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpCodeSession<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpCodeSession { + pub fn new(client: &WechatCpClient) -> WechatCpCodeSession<'_, T> { WechatCpCodeSession { client, } diff --git a/src/wechat/cp/api/department.rs b/src/wechat/cp/api/department.rs index 06912ba..600bc3b 100644 --- a/src/wechat/cp/api/department.rs +++ b/src/wechat/cp/api/department.rs @@ -14,7 +14,7 @@ pub struct WechatCpDepartment<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpDepartment<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpDepartment { + pub fn new(client: &WechatCpClient) -> WechatCpDepartment<'_, T> { WechatCpDepartment { client, } diff --git a/src/wechat/cp/api/external_contact.rs b/src/wechat/cp/api/external_contact.rs index ebc561b..38e9f64 100644 --- a/src/wechat/cp/api/external_contact.rs +++ b/src/wechat/cp/api/external_contact.rs @@ -15,7 +15,7 @@ pub struct WechatCpExternalContact<'a, T: SessionStore> { #[allow(unused)] impl<'a, T: SessionStore> WechatCpExternalContact<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpExternalContact { + pub fn new(client: &WechatCpClient) -> WechatCpExternalContact<'_, T> { WechatCpExternalContact { client, } @@ -750,7 +750,7 @@ pub struct ExternalContact { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExternalProfile { pub external_corp_name: Option, - pub external_attr: Option, + pub external_attr: Option, pub wechat_channels: Option, } @@ -762,7 +762,7 @@ pub struct WechatChannel { #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ExternalAttribute { +pub struct ExternalContactAttribute { #[serde(rename = "type")] pub r#type: Option, pub name: Option, @@ -1103,11 +1103,11 @@ pub struct Behavior { pub struct WechatCpUserExternalGroupChatStatistic { pub total: Vec, pub next_offset: Vec, - pub items: Vec, + pub items: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct StatisticItem { +pub struct ExternalStatisticItem { pub owner: Option, pub data: Option, } diff --git a/src/wechat/cp/api/group_robot.rs b/src/wechat/cp/api/group_robot.rs index 8a5cc44..b8ed392 100644 --- a/src/wechat/cp/api/group_robot.rs +++ b/src/wechat/cp/api/group_robot.rs @@ -15,7 +15,7 @@ pub struct WechatCpGroupRobot<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpGroupRobot<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpGroupRobot { + pub fn new(client: &WechatCpClient) -> WechatCpGroupRobot<'_, T> { WechatCpGroupRobot { client, } @@ -133,14 +133,14 @@ impl<'a, T: SessionStore> WechatCpGroupRobot<'a, T> { //---------------------------------------------------------------------------------------------------------------------------- #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WechatCpMenuInfo { +pub struct WechatCpBootMenuInfo { /// 企业编号 - pub buttons: Vec, - pub match_rule: Option, + pub buttons: Vec, + pub match_rule: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WechatCpMenuButton { +pub struct WechatCpBootMenuButton { ///
     /// 菜单的响应动作类型.
     /// view表示网页类型,
@@ -182,12 +182,12 @@ pub struct WechatCpMenuButton {
     /// miniprogram类型必须
     /// 
pub pagepath: Option, - pub sub_button: Vec, + pub sub_button: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WechatCpMenuRule { +pub struct WechatCpBootMenuRule { pub tag_id: Option, pub sex: Option, pub province: Option, diff --git a/src/wechat/cp/api/media.rs b/src/wechat/cp/api/media.rs index e83ac5b..011c6d2 100644 --- a/src/wechat/cp/api/media.rs +++ b/src/wechat/cp/api/media.rs @@ -20,7 +20,7 @@ pub struct WechatCpMedia<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpMedia<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpMedia { + pub fn new(client: &WechatCpClient) -> WechatCpMedia<'_, T> { WechatCpMedia { client, } diff --git a/src/wechat/cp/api/menu.rs b/src/wechat/cp/api/menu.rs index ab68e67..68cda0a 100644 --- a/src/wechat/cp/api/menu.rs +++ b/src/wechat/cp/api/menu.rs @@ -14,7 +14,7 @@ pub struct WechatCpMenu<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpMenu<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpMenu { + pub fn new(client: &WechatCpClient) -> WechatCpMenu<'_, T> { WechatCpMenu { client, } diff --git a/src/wechat/cp/api/message.rs b/src/wechat/cp/api/message.rs index e40f20e..1db97ab 100644 --- a/src/wechat/cp/api/message.rs +++ b/src/wechat/cp/api/message.rs @@ -14,7 +14,7 @@ pub struct WechatCpMessage<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpMessage<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpMessage { + pub fn new(client: &WechatCpClient) -> WechatCpMessage<'_, T> { WechatCpMessage { client, } @@ -297,12 +297,12 @@ pub struct MultipleSelect { /// 应用消息发送统计信息 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WechatCpMessageSendStatistics { - pub statistics: Option>, + pub statistics: Option>, } /// 应用消息发送统计信息 #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct StatisticItem { +pub struct MessageStatisticItem { /// 应用名 pub app_name: Option, /// 应用id diff --git a/src/wechat/cp/api/oauth2.rs b/src/wechat/cp/api/oauth2.rs index 88cf9eb..6dbca3a 100644 --- a/src/wechat/cp/api/oauth2.rs +++ b/src/wechat/cp/api/oauth2.rs @@ -14,7 +14,7 @@ pub struct WechatCpOauth2<'a, T: SessionStore> { #[allow(unused)] impl<'a, T: SessionStore> WechatCpOauth2<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpOauth2 { + pub fn new(client: &WechatCpClient) -> WechatCpOauth2<'_, T> { WechatCpOauth2 { client, } diff --git a/src/wechat/cp/api/tag.rs b/src/wechat/cp/api/tag.rs index df675c0..b831333 100644 --- a/src/wechat/cp/api/tag.rs +++ b/src/wechat/cp/api/tag.rs @@ -14,7 +14,7 @@ pub struct WechatCpTag<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpTag<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpTag { + pub fn new(client: &WechatCpClient) -> WechatCpTag<'_, T> { WechatCpTag { client, } @@ -147,7 +147,7 @@ pub struct WechatCpUserInfo { pub qr_code: Option, pub positions: Option>, /// 成员对外信息 - pub external_attrs: Option>, + pub external_attrs: Option>, pub external_position: Option, pub external_corp_name: Option, pub direct_leader: Option>, @@ -156,7 +156,7 @@ pub struct WechatCpUserInfo { #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ExternalAttribute { +pub struct ExternalTagAttribute { /// 属性类型: 0-本文 1-网页 2-小程序. #[serde(rename = "type")] pub r#type: Option, diff --git a/src/wechat/cp/api/user.rs b/src/wechat/cp/api/user.rs index b6545ad..bb11052 100644 --- a/src/wechat/cp/api/user.rs +++ b/src/wechat/cp/api/user.rs @@ -14,7 +14,7 @@ pub struct WechatCpUser<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpUser<'a, T> { #[inline] - pub fn new(client: &WechatCpClient) -> WechatCpUser { + pub fn new(client: &WechatCpClient) -> WechatCpUser<'_, T> { WechatCpUser { client, } diff --git a/src/wechat/cp/events/contact_change.rs b/src/wechat/cp/events/contact_change.rs index 9f02c72..80735a7 100644 --- a/src/wechat/cp/events/contact_change.rs +++ b/src/wechat/cp/events/contact_change.rs @@ -70,17 +70,17 @@ pub struct CpContactCreateUserEvent { #[serde(rename="BizMail")] pub biz_mail: Option, #[serde(rename="ExtAttr")] - pub ext_attrs: Option, + pub ext_attrs: Option, } #[derive(Debug, Serialize, Deserialize, Clone)] -pub struct CpExtAttrItemText { +pub struct CpContactChangeExtAttrItemText { #[serde(rename = "Value")] pub value: String, } #[derive(Debug, Serialize, Deserialize, Clone)] -pub struct CpExtAttrItemWeb { +pub struct CpContactChangeExtAttrItemWeb { #[serde(rename="Title")] pub title: String, #[serde(rename="Url")] @@ -161,25 +161,25 @@ pub struct CpContactUpdateUserEvent { #[serde(rename="BizMail")] pub biz_mail: Option, #[serde(rename="ExtAttr")] - pub ext_attrs: Option, + pub ext_attrs: Option, } #[derive(Debug, Serialize, Deserialize,Clone)] -pub struct ExtAttrs { +pub struct ExContactChangetAttrs { #[serde(rename = "Item")] - items: Vec + items: Vec } #[derive(Debug, Serialize, Deserialize,Clone)] -pub struct ExtAttrItem { +pub struct ExtContactChangeAttrItem { #[serde(rename = "Name")] name: String, #[serde(rename = "Type")] attr_type: u32, #[serde(rename="Text")] - pub text: Option, + pub text: Option, #[serde(rename="Web")] - pub web: Option, + pub web: Option, } diff --git a/src/wechat/cp/mod.rs b/src/wechat/cp/mod.rs index 5c135e2..7eed705 100644 --- a/src/wechat/cp/mod.rs +++ b/src/wechat/cp/mod.rs @@ -38,7 +38,7 @@ pub struct WechatCpClient { #[allow(unused)] #[derive(Serialize, Deserialize)] -pub struct AccessTokenResponse{ +pub struct CpAccessTokenResponse{ pub access_token: String, pub expires_in: i64, } @@ -144,7 +144,7 @@ impl WechatCpClient { (CORPID.to_string(), self.corp_id.to_string()), (CORPSECRET.to_string(), self.corp_secret.to_string()), ]).method(Method::Get).req_type(RequestType::Json); - let res = self.client.request(req).await?.json::()?; + let res = self.client.request(req).await?.json::()?; let token = res.access_token; let expires_in = res.expires_in; // 预留200秒的时间 @@ -338,57 +338,57 @@ impl WechatCpClient { } /// codesssion相关服务 - pub fn code_session(&self) -> WechatCpCodeSession { + pub fn code_session(&self) -> WechatCpCodeSession<'_, T> { WechatCpCodeSession::new(self) } /// 媒体操作接口 - pub fn media(&self) -> WechatCpMedia { + pub fn media(&self) -> WechatCpMedia<'_, T> { WechatCpMedia::new(self) } /// 自建应用 - pub fn agent(&self) -> WechatCpAgent { + pub fn agent(&self) -> WechatCpAgent<'_, T> { WechatCpAgent::new(self) } /// 部门 - pub fn department(&self) -> WechatCpDepartment { + pub fn department(&self) -> WechatCpDepartment<'_, T> { WechatCpDepartment::new(self) } /// 外部联系人 - pub fn external_contact(&self) -> WechatCpExternalContact { + pub fn external_contact(&self) -> WechatCpExternalContact<'_, T> { WechatCpExternalContact::new(self) } /// 群机器人 - pub fn group_robot(&self) -> WechatCpGroupRobot { + pub fn group_robot(&self) -> WechatCpGroupRobot<'_, T> { WechatCpGroupRobot::new(self) } /// 菜单 - pub fn menu(&self) -> WechatCpMenu { + pub fn menu(&self) -> WechatCpMenu<'_, T> { WechatCpMenu::new(self) } /// 消息 - pub fn message(&self) -> WechatCpMessage { + pub fn message(&self) -> WechatCpMessage<'_, T> { WechatCpMessage::new(self) } /// 认证 - pub fn oauth2(&self) -> WechatCpOauth2 { + pub fn oauth2(&self) -> WechatCpOauth2<'_, T> { WechatCpOauth2::new(self) } /// 标签 - pub fn tag(&self) -> WechatCpTag { + pub fn tag(&self) -> WechatCpTag<'_, T> { WechatCpTag::new(self) } /// 用户 - pub fn user(&self) -> WechatCpUser { + pub fn user(&self) -> WechatCpUser<'_, T> { WechatCpUser::new(self) } diff --git a/src/wechat/cp/tp/agent.rs b/src/wechat/cp/tp/agent.rs index 514bed5..5a1b4e0 100644 --- a/src/wechat/cp/tp/agent.rs +++ b/src/wechat/cp/tp/agent.rs @@ -14,7 +14,7 @@ pub struct WechatCpTpAgent<'a, T: SessionStore> { #[allow(unused)] impl<'a, T: SessionStore> WechatCpTpAgent<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpAgent { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpAgent<'_, T> { WechatCpTpAgent { client, } diff --git a/src/wechat/cp/tp/auth.rs b/src/wechat/cp/tp/auth.rs index b203263..ddd5775 100644 --- a/src/wechat/cp/tp/auth.rs +++ b/src/wechat/cp/tp/auth.rs @@ -13,7 +13,7 @@ pub struct WechatCpTpAuth<'a, T: SessionStore> { #[allow(unused)] impl<'a, T: SessionStore> WechatCpTpAuth<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpAuth { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpAuth<'_, T> { WechatCpTpAuth { client, } diff --git a/src/wechat/cp/tp/department.rs b/src/wechat/cp/tp/department.rs index 05ee0b4..1699d4e 100644 --- a/src/wechat/cp/tp/department.rs +++ b/src/wechat/cp/tp/department.rs @@ -15,7 +15,7 @@ pub struct WechatCpTpDepartment<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpTpDepartment<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpDepartment { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpDepartment<'_, T> { WechatCpTpDepartment { client, } diff --git a/src/wechat/cp/tp/license.rs b/src/wechat/cp/tp/license.rs index d093514..441dbfc 100644 --- a/src/wechat/cp/tp/license.rs +++ b/src/wechat/cp/tp/license.rs @@ -15,7 +15,7 @@ pub struct WechatCpTpLicense<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpTpLicense<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpLicense { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpLicense<'_, T> { WechatCpTpLicense { client, } diff --git a/src/wechat/cp/tp/media.rs b/src/wechat/cp/tp/media.rs index 4bd830c..d9d3953 100644 --- a/src/wechat/cp/tp/media.rs +++ b/src/wechat/cp/tp/media.rs @@ -18,7 +18,7 @@ pub struct WechatCpTpMedia<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpTpMedia<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpMedia { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpMedia<'_, T> { WechatCpTpMedia { client, } diff --git a/src/wechat/cp/tp/mod.rs b/src/wechat/cp/tp/mod.rs index 079e4f1..ac4a802 100644 --- a/src/wechat/cp/tp/mod.rs +++ b/src/wechat/cp/tp/mod.rs @@ -5,7 +5,7 @@ use serde_json::{json, Value}; use crate::{session::SessionStore, request::{RequestType}, WechatCommonResponse, LabradorResult, WechatCrypto, current_timestamp, LabraError, JsapiTicket, JsapiSignature, get_timestamp, get_nonce_str, APIClient, WechatRequest, LabraResponse, LabraRequest, SimpleStorage, WechatCpProviderToken}; use crate::wechat::cp::constants::{ACCESS_TOKEN, ACCESS_TOKEN_KEY, AGENT_CONFIG, AUTH_URL_INSTALL, PROVIDER_ACCESS_TOKEN, SUITE_ACCESS_TOKEN, TYPE}; use crate::wechat::cp::method::WechatCpMethod; -use crate::wechat::cp::AccessTokenResponse; +use crate::wechat::cp::CpAccessTokenResponse; mod tag; mod license; @@ -285,14 +285,14 @@ impl WechatCpTpClient { ///
     /// 获取企业凭证
     /// 
- pub async fn get_corp_token(&self, auth_corpid: &str, permanent_code: &str) -> LabradorResult { + pub async fn get_corp_token(&self, auth_corpid: &str, permanent_code: &str) -> LabradorResult { self.get_corp_token_force(auth_corpid, permanent_code, false).await } ///
     /// 获取企业凭证, 支持强制刷新
     /// 
- pub async fn get_corp_token_force(&self, auth_corpid: &str, permanent_code: &str, force_refresh: bool) -> LabradorResult { + pub async fn get_corp_token_force(&self, auth_corpid: &str, permanent_code: &str, force_refresh: bool) -> LabradorResult { let session = self.client.session(); let token_key = format!("{}_corp_access_token_cp", auth_corpid); let expires_key = format!("{}_corp_access_token_expires_at_cp", auth_corpid); @@ -306,7 +306,7 @@ impl WechatCpTpClient { "permanent_code": permanent_code, }); let v = self.client.post(WechatCpMethod::GetCorpToken, vec![], req, RequestType::Json).await?.json::()?; - let result = WechatCommonResponse::parse::(v)?; + let result = WechatCommonResponse::parse::(v)?; let token = result.access_token.to_string(); let expires_in = result.expires_in; // 预留200秒的时间 @@ -315,7 +315,7 @@ impl WechatCpTpClient { session.set(&expires_key, expires_at, Some(expires_in as usize)); Ok(result) } else { - Ok(AccessTokenResponse { access_token: token.to_string(), expires_in: expires_at }) + Ok(CpAccessTokenResponse { access_token: token.to_string(), expires_in: expires_at }) } } @@ -535,42 +535,42 @@ impl WechatCpTpClient { } /// 部门 - pub fn department(&self) -> WechatCpTpDepartment { + pub fn department(&self) -> WechatCpTpDepartment<'_, T> { WechatCpTpDepartment::new(self) } /// 接口调用许可 - pub fn license(&self) -> WechatCpTpLicense { + pub fn license(&self) -> WechatCpTpLicense<'_, T> { WechatCpTpLicense::new(self) } /// 媒体 - pub fn media(&self) -> WechatCpTpMedia { + pub fn media(&self) -> WechatCpTpMedia<'_, T> { WechatCpTpMedia::new(self) } /// 订单 - pub fn order(&self) -> WechatCpTpOrder { + pub fn order(&self) -> WechatCpTpOrder<'_, T> { WechatCpTpOrder::new(self) } /// 标签 - pub fn tag(&self) -> WechatCpTpTag { + pub fn tag(&self) -> WechatCpTpTag<'_, T> { WechatCpTpTag::new(self) } /// 用户 - pub fn user(&self) -> WechatCpTpUser { + pub fn user(&self) -> WechatCpTpUser<'_, T> { WechatCpTpUser::new(self) } /// 第三方应用 - pub fn agent(&self) -> WechatCpTpAgent { + pub fn agent(&self) -> WechatCpTpAgent<'_, T> { WechatCpTpAgent::new(self) } /// 身份 - pub fn auth(&self) -> WechatCpTpAuth { + pub fn auth(&self) -> WechatCpTpAuth<'_, T> { WechatCpTpAuth::new(self) } } diff --git a/src/wechat/cp/tp/order.rs b/src/wechat/cp/tp/order.rs index 091bc08..b98477b 100644 --- a/src/wechat/cp/tp/order.rs +++ b/src/wechat/cp/tp/order.rs @@ -14,7 +14,7 @@ pub struct WechatCpTpOrder<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpTpOrder<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpOrder { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpOrder<'_, T> { WechatCpTpOrder { client, } diff --git a/src/wechat/cp/tp/tag.rs b/src/wechat/cp/tp/tag.rs index 7a4c6c9..ae2285a 100644 --- a/src/wechat/cp/tp/tag.rs +++ b/src/wechat/cp/tp/tag.rs @@ -13,7 +13,7 @@ pub struct WechatCpTpTag<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpTpTag<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpTag { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpTag<'_, T> { WechatCpTpTag { client, } diff --git a/src/wechat/cp/tp/user.rs b/src/wechat/cp/tp/user.rs index e7e48b3..cff53c4 100644 --- a/src/wechat/cp/tp/user.rs +++ b/src/wechat/cp/tp/user.rs @@ -15,7 +15,7 @@ pub struct WechatCpTpUser<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatCpTpUser<'a, T> { #[inline] - pub fn new(client: &WechatCpTpClient) -> WechatCpTpUser { + pub fn new(client: &WechatCpTpClient) -> WechatCpTpUser<'_, T> { WechatCpTpUser { client, } @@ -188,9 +188,9 @@ impl<'a, T: SessionStore> WechatCpTpUser<'a, T> { /// 第三方应用需拥有“企业客户”权限。 /// 第三方应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。 /// - pub async fn get_external_contact(&self, userid: &str) -> LabradorResult { + pub async fn get_external_contact(&self, userid: &str) -> LabradorResult { let v = self.client.get(WechatCpMethod::User(CpUserMethod::GetExternalContact(userid.to_string())), vec![],RequestType::Json).await?.json::()?; - WechatCommonResponse::parse::(v) + WechatCommonResponse::parse::(v) } } @@ -209,7 +209,7 @@ pub struct WxCpTpUseridToOpenidResponse { } /// 外部联系人详情 #[derive(Debug, Clone,Serialize, Deserialize)] -pub struct WechatCpUserExternalContactInfo { +pub struct WechatCpTpUserExternalContactInfo { pub external_contact: Option, pub follow_user: Option, } \ No newline at end of file diff --git a/src/wechat/cryptos/mod.rs b/src/wechat/cryptos/mod.rs index d9640f7..dcbb90b 100644 --- a/src/wechat/cryptos/mod.rs +++ b/src/wechat/cryptos/mod.rs @@ -152,6 +152,7 @@ impl WechatCrypto { /// encrypted_data 加密数据 pub fn decrypt_data(session_key: &str, encrypted_data: &str, iv: &str) -> LabradorResult { let key = base64::decode(&session_key)?; + let iv = base64::decode(iv)?; let prp = PrpCrypto::new(key); let encrypted_data = base64::decode(encrypted_data)?; let encrypt_content = prp.aes_128_cbc_decrypt_data(encrypted_data, Some(iv))?; diff --git a/src/wechat/miniapp/api/codesession.rs b/src/wechat/miniapp/api/codesession.rs index dba1134..db028da 100644 --- a/src/wechat/miniapp/api/codesession.rs +++ b/src/wechat/miniapp/api/codesession.rs @@ -15,7 +15,7 @@ pub struct WechatMaCodeSession<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMaCodeSession<'a, T> { #[inline] - pub fn new(client: &WechatMaClient) -> WechatMaCodeSession { + pub fn new(client: &WechatMaClient) -> WechatMaCodeSession<'_, T> { WechatMaCodeSession { client, } diff --git a/src/wechat/miniapp/api/media.rs b/src/wechat/miniapp/api/media.rs index b8d5048..910d2b5 100644 --- a/src/wechat/miniapp/api/media.rs +++ b/src/wechat/miniapp/api/media.rs @@ -19,7 +19,7 @@ pub struct WechatMaMedia<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMaMedia<'a, T> { #[inline] - pub fn new(client: &WechatMaClient) -> WechatMaMedia { + pub fn new(client: &WechatMaClient) -> WechatMaMedia<'_, T> { WechatMaMedia { client, } diff --git a/src/wechat/miniapp/api/message.rs b/src/wechat/miniapp/api/message.rs index cc65964..14b1aa2 100644 --- a/src/wechat/miniapp/api/message.rs +++ b/src/wechat/miniapp/api/message.rs @@ -17,7 +17,7 @@ pub struct WechatMaMessage<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMaMessage<'a, T> { #[inline] - pub fn new(client: &WechatMaClient) -> WechatMaMessage { + pub fn new(client: &WechatMaClient) -> WechatMaMessage<'_, T> { WechatMaMessage { client, } diff --git a/src/wechat/miniapp/api/qrcode.rs b/src/wechat/miniapp/api/qrcode.rs index 17156ce..499a6a8 100644 --- a/src/wechat/miniapp/api/qrcode.rs +++ b/src/wechat/miniapp/api/qrcode.rs @@ -20,7 +20,7 @@ pub struct WechatMaQrcode<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMaQrcode<'a, T> { #[inline] - pub fn new(client: &WechatMaClient) -> WechatMaQrcode { + pub fn new(client: &WechatMaClient) -> WechatMaQrcode<'_, T> { WechatMaQrcode { client, } diff --git a/src/wechat/miniapp/api/user.rs b/src/wechat/miniapp/api/user.rs index df1dec2..9f680d3 100644 --- a/src/wechat/miniapp/api/user.rs +++ b/src/wechat/miniapp/api/user.rs @@ -17,7 +17,7 @@ pub struct WechatMaUser<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMaUser<'a, T> { #[inline] - pub fn new(client: &WechatMaClient) -> WechatMaUser { + pub fn new(client: &WechatMaClient) -> WechatMaUser<'_, T> { WechatMaUser { client, } diff --git a/src/wechat/miniapp/mod.rs b/src/wechat/miniapp/mod.rs index ed9d1d7..3d464d3 100644 --- a/src/wechat/miniapp/mod.rs +++ b/src/wechat/miniapp/mod.rs @@ -137,24 +137,24 @@ impl WechatMaClient { } /// codesssion相关服务 - pub fn code_session(&self) -> WechatMaCodeSession { + pub fn code_session(&self) -> WechatMaCodeSession<'_, T> { WechatMaCodeSession::new(self) } /// 二维码相关操作接口 - pub fn qrcode(&self) -> WechatMaQrcode { + pub fn qrcode(&self) -> WechatMaQrcode<'_, T> { WechatMaQrcode::new(self) } /// 用户相关操作接口 - pub fn user(&self) -> WechatMaUser { + pub fn user(&self) -> WechatMaUser<'_, T> { WechatMaUser::new(self) } /// 媒体操作接口 - pub fn media(&self) -> WechatMaMedia { + pub fn media(&self) -> WechatMaMedia<'_, T> { WechatMaMedia::new(self) } /// 媒体操作接口 - pub fn message(&self) -> WechatMaMessage { + pub fn message(&self) -> WechatMaMessage<'_, T> { WechatMaMessage::new(self) } diff --git a/src/wechat/mp/api/card.rs b/src/wechat/mp/api/card.rs index 7c7538a..ae7ee4f 100644 --- a/src/wechat/mp/api/card.rs +++ b/src/wechat/mp/api/card.rs @@ -17,7 +17,7 @@ pub struct WechatMpCard<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMpCard<'a, T> { #[inline] - pub fn new(client: &WechatMpClient) -> WechatMpCard { + pub fn new(client: &WechatMpClient) -> WechatMpCard<'_, T> { WechatMpCard { client, } diff --git a/src/wechat/mp/api/customservice.rs b/src/wechat/mp/api/customservice.rs index 76358bb..18a12c8 100644 --- a/src/wechat/mp/api/customservice.rs +++ b/src/wechat/mp/api/customservice.rs @@ -17,7 +17,7 @@ pub struct WechatMpCustomService<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMpCustomService<'a, T> { #[inline] - pub fn new(client: &WechatMpClient) -> WechatMpCustomService { + pub fn new(client: &WechatMpClient) -> WechatMpCustomService<'_, T> { WechatMpCustomService { client, } diff --git a/src/wechat/mp/api/media.rs b/src/wechat/mp/api/media.rs index de1f226..23de7a2 100644 --- a/src/wechat/mp/api/media.rs +++ b/src/wechat/mp/api/media.rs @@ -38,7 +38,7 @@ pub struct WechatMpMedia<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMpMedia<'a, T> { #[inline] - pub fn new(client: &WechatMpClient) -> WechatMpMedia { + pub fn new(client: &WechatMpClient) -> WechatMpMedia<'_, T> { WechatMpMedia { client, } diff --git a/src/wechat/mp/api/member.rs b/src/wechat/mp/api/member.rs index 12deda5..3ad6d37 100644 --- a/src/wechat/mp/api/member.rs +++ b/src/wechat/mp/api/member.rs @@ -17,7 +17,7 @@ pub struct WechatMpMember<'a, T: SessionStore> { impl<'a, T: SessionStore> WechatMpMember<'a, T> { #[inline] - pub fn new(client: &WechatMpClient) -> WechatMpMember { + pub fn new(client: &WechatMpClient) -> WechatMpMember<'_, T> { WechatMpMember { client, } @@ -26,7 +26,7 @@ impl<'a, T: SessionStore> WechatMpMember<'a, T> { ///
     /// 会员卡创建接口
     /// 
- pub async fn create_member_card_custom(&self, req: D) -> LabradorResult { + pub async fn create_member_card_custom(&self, req: D) -> LabradorResult { let v = serde_json::to_value(req)?; let req = serde_json::from_value::(v)?; self.create_member_card(req).await @@ -35,10 +35,10 @@ impl<'a, T: SessionStore> WechatMpMember<'a, T> { ///
     /// 会员卡创建接口
     /// 
- pub async fn create_member_card(&self, req: WechatMpMemberCardCreateRequest) -> LabradorResult { + pub async fn create_member_card(&self, req: WechatMpMemberCardCreateRequest) -> LabradorResult { req.valid_check()?; let v = self.client.post(WechatMpMethod::MemberCard(MpMemeberCardMethod::Create), vec![], req, RequestType::Json).await?.json::()?; - WechatCommonResponse::parse::(v) + WechatCommonResponse::parse::(v) } ///
@@ -659,7 +659,7 @@ pub struct DateInfo {
 
 /// 使用日期,有效期的信息.
 #[derive(Debug, Clone, Serialize, Deserialize)]
-pub struct WechatMpCardCreateResponse {
+pub struct WechatMpMemberCardCreateResponse {
     pub card_id: String,
 }
 
diff --git a/src/wechat/mp/api/menu.rs b/src/wechat/mp/api/menu.rs
index 08c47e3..c9d51d1 100644
--- a/src/wechat/mp/api/menu.rs
+++ b/src/wechat/mp/api/menu.rs
@@ -34,7 +34,7 @@ pub struct WechatMpMenu<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpMenu<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpMenu {
+    pub fn new(client: &WechatMpClient) -> WechatMpMenu<'_, T> {
         WechatMpMenu {
             client,
         }
diff --git a/src/wechat/mp/api/oauth2.rs b/src/wechat/mp/api/oauth2.rs
index 3babb95..145e291 100644
--- a/src/wechat/mp/api/oauth2.rs
+++ b/src/wechat/mp/api/oauth2.rs
@@ -14,7 +14,7 @@ pub struct WechatMpOauth2<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpOauth2<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpOauth2 {
+    pub fn new(client: &WechatMpClient) -> WechatMpOauth2<'_, T> {
         WechatMpOauth2 {
             client,
         }
diff --git a/src/wechat/mp/api/ocr.rs b/src/wechat/mp/api/ocr.rs
index 35e35b3..707df8d 100644
--- a/src/wechat/mp/api/ocr.rs
+++ b/src/wechat/mp/api/ocr.rs
@@ -20,7 +20,7 @@ pub struct WechatMpOcr<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpOcr<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpOcr {
+    pub fn new(client: &WechatMpClient) -> WechatMpOcr<'_, T> {
         WechatMpOcr {
             client,
         }
diff --git a/src/wechat/mp/api/qrcode.rs b/src/wechat/mp/api/qrcode.rs
index 4b4db68..2b5822b 100644
--- a/src/wechat/mp/api/qrcode.rs
+++ b/src/wechat/mp/api/qrcode.rs
@@ -13,7 +13,7 @@ pub struct WechatMpQRCode<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpQRCode<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpQRCode {
+    pub fn new(client: &WechatMpClient) -> WechatMpQRCode<'_, T> {
         WechatMpQRCode {
             client,
         }
@@ -133,7 +133,7 @@ pub struct PermQRCodeRequest {
 }
 
 #[derive(Debug, Clone,  Serialize, Deserialize)]
-pub struct MiniQRCodeRequest {
+pub struct MpMiniQRCodeRequest {
     scene: String,
     page: String,
 }
@@ -181,7 +181,7 @@ impl TempQRCodeRequest {
 }
 
 #[allow(unused)]
-impl MiniQRCodeRequest {
+impl MpMiniQRCodeRequest {
     fn to_json(&self) -> Value {
         json!({
             "scene": self.scene,
diff --git a/src/wechat/mp/api/subscribe_msg.rs b/src/wechat/mp/api/subscribe_msg.rs
index 95d95f9..2eb2eb4 100644
--- a/src/wechat/mp/api/subscribe_msg.rs
+++ b/src/wechat/mp/api/subscribe_msg.rs
@@ -14,7 +14,7 @@ pub struct WechatMpSubscribeMessage<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpSubscribeMessage<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpSubscribeMessage {
+    pub fn new(client: &WechatMpClient) -> WechatMpSubscribeMessage<'_, T> {
         WechatMpSubscribeMessage {
             client,
         }
diff --git a/src/wechat/mp/api/template_msg.rs b/src/wechat/mp/api/template_msg.rs
index 58393b5..15d1e06 100644
--- a/src/wechat/mp/api/template_msg.rs
+++ b/src/wechat/mp/api/template_msg.rs
@@ -14,7 +14,7 @@ pub struct WechatMpTemplateMessage<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpTemplateMessage<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpTemplateMessage {
+    pub fn new(client: &WechatMpClient) -> WechatMpTemplateMessage<'_, T> {
         WechatMpTemplateMessage {
             client,
         }
diff --git a/src/wechat/mp/api/user.rs b/src/wechat/mp/api/user.rs
index cf0425b..bc9e6f3 100644
--- a/src/wechat/mp/api/user.rs
+++ b/src/wechat/mp/api/user.rs
@@ -16,7 +16,7 @@ pub struct WechatMpUser<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpUser<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpUser {
+    pub fn new(client: &WechatMpClient) -> WechatMpUser<'_, T> {
         WechatMpUser {
             client,
         }
diff --git a/src/wechat/mp/api/wifi.rs b/src/wechat/mp/api/wifi.rs
index ffffad1..45d4777 100644
--- a/src/wechat/mp/api/wifi.rs
+++ b/src/wechat/mp/api/wifi.rs
@@ -16,7 +16,7 @@ pub struct WechatMpWifi<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WechatMpWifi<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatMpClient) -> WechatMpWifi {
+    pub fn new(client: &WechatMpClient) -> WechatMpWifi<'_, T> {
         WechatMpWifi {
             client,
         }
diff --git a/src/wechat/mp/mod.rs b/src/wechat/mp/mod.rs
index 3478379..25d3dd5 100644
--- a/src/wechat/mp/mod.rs
+++ b/src/wechat/mp/mod.rs
@@ -31,7 +31,7 @@ pub struct WechatMpClient {
 
 #[allow(unused)]
 #[derive(Serialize, Deserialize)]
-pub struct AccessTokenResponse{
+pub struct MpAccessTokenResponse{
     pub access_token: String,
     pub expires_in: i64,
 }
@@ -122,7 +122,7 @@ impl WechatMpClient {
                 (SECRET.to_string(), self.client.secret.to_string()),
             ]).method(Method::Get).req_type(RequestType::Json);
             let v = self.client.request(req).await?.json::()?;
-            let res = WechatCommonResponse::parse::(v)?;
+            let res = WechatCommonResponse::parse::(v)?;
             let token = res.access_token;
             let expires_in = res.expires_in;
             // 预留200秒的时间
@@ -299,52 +299,52 @@ impl WechatMpClient {
     }
 
     /// 用户相关服务
-    pub fn user(&self) -> WechatMpUser {
+    pub fn user(&self) -> WechatMpUser<'_, T> {
         WechatMpUser::new(self)
     }
 
     /// Oauth2授权相关服务
-    pub fn oauth2(&self) -> WechatMpOauth2 {
+    pub fn oauth2(&self) -> WechatMpOauth2<'_, T> {
         WechatMpOauth2::new(self)
     }
 
     /// qrcode相关服务
-    pub fn qrcode(&self) -> WechatMpQRCode {
+    pub fn qrcode(&self) -> WechatMpQRCode<'_, T> {
         WechatMpQRCode::new(self)
     }
 
     /// 客服相关服务
-    pub fn custom_service(&self) -> WechatMpCustomService {
+    pub fn custom_service(&self) -> WechatMpCustomService<'_, T> {
         WechatMpCustomService::new(self)
     }
 
     /// 菜单相关服务
-    pub fn menu(&self) -> WechatMpMenu {
+    pub fn menu(&self) -> WechatMpMenu<'_, T> {
         WechatMpMenu::new(self)
     }
 
     /// 多媒体服务
-    pub fn media(&self) -> WechatMpMedia {
+    pub fn media(&self) -> WechatMpMedia<'_, T> {
         WechatMpMedia::new(self)
     }
 
     /// 模板消息服务
-    pub fn template_msg(&self) -> WechatMpTemplateMessage {
+    pub fn template_msg(&self) -> WechatMpTemplateMessage<'_, T> {
         WechatMpTemplateMessage::new(self)
     }
 
     /// 订阅消息服务
-    pub fn subscribe_msg(&self) -> WechatMpSubscribeMessage {
+    pub fn subscribe_msg(&self) -> WechatMpSubscribeMessage<'_, T> {
         WechatMpSubscribeMessage::new(self)
     }
 
     /// Wifi服务
-    pub fn wifi(&self) -> WechatMpWifi {
+    pub fn wifi(&self) -> WechatMpWifi<'_, T> {
         WechatMpWifi::new(self)
     }
 
     /// OCR服务
-    pub fn ocr(&self) -> WechatMpOcr {
+    pub fn ocr(&self) -> WechatMpOcr<'_, T> {
         WechatMpOcr::new(self)
     }
 
diff --git a/src/wechat/pay/api/wxpay.rs b/src/wechat/pay/api/wxpay.rs
index e49d790..7cc71dc 100644
--- a/src/wechat/pay/api/wxpay.rs
+++ b/src/wechat/pay/api/wxpay.rs
@@ -14,7 +14,7 @@ pub struct WxPay<'a, T: SessionStore> {
 impl<'a, T: SessionStore> WxPay<'a, T> {
 
     #[inline]
-    pub fn new(client: &WechatPayClient) -> WxPay {
+    pub fn new(client: &WechatPayClient) -> WxPay<'_, T> {
         WxPay {
             client,
         }
diff --git a/src/wechat/pay/mod.rs b/src/wechat/pay/mod.rs
index 032ca3c..e9579e3 100644
--- a/src/wechat/pay/mod.rs
+++ b/src/wechat/pay/mod.rs
@@ -352,7 +352,7 @@ impl WechatPayClient {
     }
 
     /// 微信支付服务
-    pub fn wxpay(&self) -> WxPay {
+    pub fn wxpay(&self) -> WxPay<'_, T> {
         WxPay::new(self)
     }
 
diff --git a/src/wechat/pay/request/mod.rs b/src/wechat/pay/request/mod.rs
index 516c0dd..fc2349f 100644
--- a/src/wechat/pay/request/mod.rs
+++ b/src/wechat/pay/request/mod.rs
@@ -79,7 +79,7 @@ pub struct WechatPayRequestV3 {
     pub scene_info: Option,
     /// 结算信息
     #[serde(skip_serializing_if = "Option::is_none")]
-    pub settle_info: Option,
+    pub settle_info: Option,
 }
 
 
@@ -122,7 +122,7 @@ pub struct IsvWechatPayRequestV3 {
     pub scene_info: Option,
     /// 结算信息
     #[serde(skip_serializing_if = "Option::is_none")]
-    pub settle_info: Option,
+    pub settle_info: Option,
 }
 
 #[derive(Debug, Serialize, Deserialize, Clone)]
@@ -141,7 +141,7 @@ pub struct Amount {
 }
 
 #[derive(Debug, Serialize, Deserialize, Clone)]
-pub struct SettleInfo {
+pub struct WechatSettleInfo {
     /// 是否指定分账
     pub profit_sharing: Option,
 }

From c2c2e3f2d655fefd414fef1eb86d7770a2f0238c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=BD=98=E5=AE=89?= 
Date: Wed, 31 Dec 2025 11:10:31 +0800
Subject: [PATCH 2/3] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=86=E7=9B=B8?=
 =?UTF-8?q?=E5=85=B3=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/request.rs  | 3 ++-
 src/util/prp.rs | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/request.rs b/src/request.rs
index 35468a3..018c069 100644
--- a/src/request.rs
+++ b/src/request.rs
@@ -353,7 +353,8 @@ impl  LabraRequest  where T: Serialize {
                 request = request.header(k, HeaderValue::from_str(v)?);
             }
         }
-        tracing::info!("[请求第三方接口参数] url: {}, data:{}", http_url.as_str(), data);
+        
+        tracing::info!("[请求第三方接口参数] url: {}, \n headers:{:?},\n data:{}", http_url.as_str(), &self.headers, data);
         let result = request.send().await?;
         let status = result.status();
         let remote_addr = result.remote_addr();
diff --git a/src/util/prp.rs b/src/util/prp.rs
index fa40f2e..868024d 100644
--- a/src/util/prp.rs
+++ b/src/util/prp.rs
@@ -24,7 +24,7 @@ cfg_if! {if #[cfg(not(feature = "openssl-crypto"))]{
         generic_array::GenericArray,
     };
     use aes_gcm::AeadInPlace;
-    use block_modes::{BlockMode, Cbc, Ecb, Cfb};
+    use block_modes::{BlockMode, Cbc, Ecb};
     use hmac::Mac;
     use sha1::Digest;
 }}

From 11b99ed3d96afa19537366adadefe9d7b135483a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=BD=98=E5=AE=89?= 
Date: Tue, 3 Feb 2026 13:40:23 +0800
Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dissue=20#35=E4=B8=AD?=
 =?UTF-8?q?=E7=9A=84=E9=87=91=E9=A2=9D=E6=A0=BC=E5=BC=8F=E5=8C=96=E9=97=AE?=
 =?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/alipay/response/mod.rs |  7 +++++++
 src/util/amount_serde.rs   | 31 +++++++++++++++++++++++++++++++
 src/util/mod.rs            |  2 +-
 3 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 src/util/amount_serde.rs

diff --git a/src/alipay/response/mod.rs b/src/alipay/response/mod.rs
index c4e16f7..2fe8b98 100644
--- a/src/alipay/response/mod.rs
+++ b/src/alipay/response/mod.rs
@@ -2,6 +2,7 @@ use std::collections::{BTreeMap};
 use json::JsonValue;
 use serde::{Deserialize, Serialize};
 use serde::de::{DeserializeOwned};
+use crate::amount_serde;
 
 use crate::{errors::LabraError, AlipayResponse, LabradorResult, RequestMethod};
 use crate::alipay::constants::{ALIPAY_CERT_SN, ERROR_RESPONSE_KEY, SIGN};
@@ -778,16 +779,22 @@ pub struct AlipayNotifyResponse {
     /// 
pub trade_status: Option, /// 订单金额。本次交易支付订单金额,单位为人民币(元),精确到小数点后 2 位 + #[serde(with = "amount_serde")] pub total_amount: Option, /// 实收金额。商家在交易中实际收到的款项,单位为人民币(元),精确到小数点后 2 位 + #[serde(with = "amount_serde")] pub receipt_amount: Option, /// 开票金额。用户在交易中支付的可开发票的金额,单位为人民币(元),精确到小数点后 2 位 + #[serde(with = "amount_serde")] pub invoice_amount: Option, /// 用户在交易中支付的金额,单位为人民币(元),精确到小数点后 2 位 + #[serde(with = "amount_serde")] pub buyer_pay_amount: Option, /// 使用集分宝支付金额,单位为人民币(元),精确到小数点后 2 位 + #[serde(with = "amount_serde")] pub point_amount: Option, /// 总退款金额。退款通知中,返回总退款金额,单位为人民币(元),精确到小数点后 2 位 + #[serde(with = "amount_serde")] pub refund_fee: Option, /// 订单标题/商品标题/交易标题/订单关键字等,是请求时对应参数,会在通知中原样传回 pub subject: Option, diff --git a/src/util/amount_serde.rs b/src/util/amount_serde.rs new file mode 100644 index 0000000..e36afc7 --- /dev/null +++ b/src/util/amount_serde.rs @@ -0,0 +1,31 @@ +use serde::{Serializer, Deserializer, Deserialize}; +use serde::de::Error; + +pub fn serialize(value: &Option, serializer: S) -> Result +where + S: Serializer, +{ + match value { + Some(v) => { + // 序列化时格式化为2位小数 + serializer.serialize_str(&format!("{:.2}", v)) + }, + None => serializer.serialize_none(), + } +} + +pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let s: Option = Option::deserialize(deserializer)?; + match s { + Some(str_val) => { + // 解析为f64 + str_val.parse::() + .map(Some) + .map_err(D::Error::custom) + }, + None => Ok(None), + } +} \ No newline at end of file diff --git a/src/util/mod.rs b/src/util/mod.rs index 856ddc7..4d205ee 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -5,7 +5,7 @@ use crate::prp::PrpCrypto; pub mod md5; pub mod prp; - +pub mod amount_serde; /// 请求参数 #[derive(Debug, Clone)]