use std::sync::{Arc, Weak};
use async_trait::async_trait;
use wx_rust_common::error::WxErrorException;
use wx_rust_miniapp::api::WxMaService;
use crate::api::WxOpenMaEmbeddedService;
use crate::api::WxOpenService;
use crate::api::r#impl::WxOpenMaService;
use crate::api::r#impl::base_wx_open_service_impl;
use crate::bean::WxOpenMaEmbeddedListResult;
use crate::enums::url_ma_domain::{
ma_embedded_add_url, ma_embedded_del_authorize_url, ma_embedded_del_url,
ma_embedded_get_list_url, ma_embedded_get_own_list_url, ma_embedded_set_authorize_url,
};
pub struct WxOpenMaEmbeddedServiceImpl {
wx_open_service: Weak<dyn WxOpenService>,
app_id: String,
}
impl WxOpenMaEmbeddedServiceImpl {
pub fn new(wx_open_service: Arc<dyn WxOpenService>, app_id: String) -> Self {
Self {
wx_open_service: Arc::downgrade(&wx_open_service),
app_id,
}
}
pub fn app_id(&self) -> &str {
&self.app_id
}
fn svc(&self) -> Result<Arc<dyn WxOpenService>, WxErrorException> {
self.wx_open_service
.upgrade()
.ok_or_else(|| WxErrorException::from_code(-99, "门面服务已被释放"))
}
fn ma_service(&self) -> Result<Arc<dyn WxMaService>, WxErrorException> {
let svc = self.svc()?;
let component = svc.wx_open_component_service().ok_or_else(|| {
WxErrorException::from_code(
-99,
"组件子服务未装配(getWxOpenComponentService 返回 null)",
)
})?;
let any = component
.get_wx_ma_service_by_appid(&self.app_id)
.ok_or_else(|| WxErrorException::from_code(-99, "getWxMaServiceByAppid 返回 None"))?;
let ma = any.downcast::<WxOpenMaService>().map_err(|_| {
WxErrorException::from_code(-99, "代 ma 服务 downcast 失败(缓存类型不匹配)")
})?;
Ok(ma as Arc<dyn WxMaService>)
}
}
#[async_trait]
impl WxOpenMaEmbeddedService for WxOpenMaEmbeddedServiceImpl {
async fn add_embedded(
&self,
embedded_app_id: &str,
apply_reason: &str,
) -> Result<(), WxErrorException> {
let svc = self.svc()?;
let config = svc.wx_open_config_storage();
let ma = self.ma_service()?;
let mut body = serde_json::json!({ "appid": embedded_app_id });
if !apply_reason.trim().is_empty() {
body["apply_reason"] = serde_json::Value::String(apply_reason.to_string());
}
ma.post(&ma_embedded_add_url(config.as_ref()), &body.to_string())
.await?;
Ok(())
}
async fn delete_embedded(&self, embedded_app_id: &str) -> Result<(), WxErrorException> {
let svc = self.svc()?;
let config = svc.wx_open_config_storage();
let ma = self.ma_service()?;
let body = serde_json::json!({ "appid": embedded_app_id });
ma.post(&ma_embedded_del_url(config.as_ref()), &body.to_string())
.await?;
Ok(())
}
async fn get_embedded_list(&self) -> Result<WxOpenMaEmbeddedListResult, WxErrorException> {
let svc = self.svc()?;
let config = svc.wx_open_config_storage();
let ma = self.ma_service()?;
let response = ma
.get(&ma_embedded_get_list_url(config.as_ref()), "")
.await?;
let response = base_wx_open_service_impl::normalize_errcode(&response)?;
serde_json::from_str(&response).map_err(|e| WxErrorException::Serde(e.to_string()))
}
async fn delete_authorized_embedded(
&self,
embedded_app_id: &str,
) -> Result<(), WxErrorException> {
let svc = self.svc()?;
let config = svc.wx_open_config_storage();
let ma = self.ma_service()?;
let body = serde_json::json!({ "appid": embedded_app_id });
ma.post(
&ma_embedded_del_authorize_url(config.as_ref()),
&body.to_string(),
)
.await?;
Ok(())
}
async fn get_own_list(&self) -> Result<WxOpenMaEmbeddedListResult, WxErrorException> {
let svc = self.svc()?;
let config = svc.wx_open_config_storage();
let ma = self.ma_service()?;
let url = format!("{}?num=1000", ma_embedded_get_own_list_url(config.as_ref()));
let response = ma.get(&url, "").await?;
let response = base_wx_open_service_impl::normalize_errcode(&response)?;
serde_json::from_str(&response).map_err(|e| WxErrorException::Serde(e.to_string()))
}
async fn get_own_list_with(
&self,
start: Option<i32>,
num: Option<i32>,
) -> Result<WxOpenMaEmbeddedListResult, WxErrorException> {
let start = start.unwrap_or(0);
let num = num.unwrap_or(10).min(1000);
let svc = self.svc()?;
let config = svc.wx_open_config_storage();
let ma = self.ma_service()?;
let url = format!(
"{}?start={start}&num={num}",
ma_embedded_get_own_list_url(config.as_ref())
);
let response = ma.get(&url, "").await?;
let response = base_wx_open_service_impl::normalize_errcode(&response)?;
serde_json::from_str(&response).map_err(|e| WxErrorException::Serde(e.to_string()))
}
async fn set_authorized_embedded(&self, flag: i32) -> Result<(), WxErrorException> {
let svc = self.svc()?;
let config = svc.wx_open_config_storage();
let ma = self.ma_service()?;
let body = serde_json::json!({ "flag": flag });
ma.post(
&ma_embedded_set_authorize_url(config.as_ref()),
&body.to_string(),
)
.await?;
Ok(())
}
}