use serde::{Deserialize, Serialize};
use serde::de::DeserializeOwned;
use serde_json::{Value as JsonValue, Value};
use crate::{errors::LabraError, LabradorResult, RequestMethod};
use crate::taobao::constants::ERROR_RESPONSE_KEY;
#[derive(Debug, Serialize, Deserialize)]
pub struct TaobaoResponse {
pub code: Option<i32>,
pub msg: Option<String>,
pub request_id: Option<String>,
pub sub_code: Option<String>,
pub sub_msg: Option<String>,
pub body: Option<String>,
}
impl TaobaoResponse {
pub fn new() -> Self {
Self {
code: None,
msg: None,
request_id: None,
sub_code: None,
sub_msg: None,
body: None,
}
}
pub fn parse(str: &str,method: impl RequestMethod) -> LabradorResult<Self> {
let v= serde_json::from_str(str).unwrap_or(JsonValue::Null);
let err= &v[ERROR_RESPONSE_KEY];
if !err.is_null() {
let resp = serde_json::from_str::<Self>(&err.to_string()).unwrap_or(TaobaoResponse::new());
Err(LabraError::ClientError {errcode: resp.code.to_owned().unwrap_or_default().to_string(), errmsg: resp.msg.to_owned().unwrap_or_default()})
} else {
let response = &v[&method.get_response_key()];
if !response.is_null() {
let mut resp = serde_json::from_str::<Self>(&response.to_string()).unwrap_or(TaobaoResponse::new());
if resp.code.is_none() {
resp.code = 0.into();
}
resp.body = response.to_string().into();
Ok(resp)
} else {
Err(LabraError::MissingField(format!("无法获取解析返回结果:【{}】", str)))
}
}
}
pub fn is_success(&self) -> bool {
self.code.to_owned().unwrap_or_default() == 0
}
pub fn get_biz_model<T: DeserializeOwned>(&self) -> LabradorResult<T> {
if self.is_success() {
serde_json::from_str::<T>(&self.body.to_owned().unwrap_or_default()).map_err(LabraError::from)
} else {
Err(LabraError::ClientError { errcode: self.code.to_owned().unwrap_or_default().to_string(), errmsg: self.sub_msg.to_owned().unwrap_or_default() })
}
}
}
#[derive(Debug, Deserialize,Serialize)]
pub struct DescList {
string: Option<Vec<String>>
}
#[derive(Debug, Deserialize,Serialize)]
pub struct ResultlList<T> {
pub map_data: Option<Vec<T>>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbMaterialSelectResponse {
pub total_count: Option<u64>,
pub is_default: Option<String>,
pub result_list: Option<ResultlList<MaterialSelectItem>>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct MaterialSelectItem {
pub coupon_amount: Option<u64>,
pub small_images: Option<DescList>,
pub shop_title: Option<String>,
pub item_description: Option<String>,
pub title: Option<String>,
pub coupon_start_fee: Option<String>,
pub zk_final_price: Option<String>,
pub commission_rate: Option<String>,
pub coupon_start_time: Option<String>,
pub coupon_end_time: Option<String>,
pub coupon_click_url: Option<String>,
pub pict_url: Option<String>,
pub click_url: Option<String>,
pub category_id: Option<u64>,
pub item_id: Option<u64>,
pub volume: Option<u64>,
pub seller_id: Option<u64>,
pub coupon_total_count: Option<u64>,
pub coupon_remain_count: Option<u64>,
pub user_type: Option<u8>,
pub stock: Option<u64>,
pub sell_num: Option<u64>,
pub total_stock: Option<u64>,
pub oetime: Option<String>,
pub ostime: Option<String>,
pub jdd_num: Option<u64>,
pub jdd_price: Option<String>,
pub orig_price: Option<String>,
pub level_one_category_name: Option<String>,
pub white_image: Option<String>,
pub short_title: Option<String>,
pub tmall_play_activity_info: Option<String>,
pub word_list: Option<WordData>,
pub category_name: Option<String>,
pub new_user_price: Option<String>,
pub coupon_info: Option<String>,
pub coupon_share_url: Option<String>,
pub nick: Option<String>,
pub reserve_price: Option<String>,
pub ju_online_end_time: Option<String>,
pub ju_online_start_time: Option<String>,
pub maochao_play_end_time: Option<String>,
pub maochao_play_start_time: Option<String>,
pub maochao_play_conditions: Option<String>,
pub maochao_play_discounts: Option<String>,
pub maochao_play_discount_type: Option<String>,
pub maochao_play_free_post_fee: Option<String>,
pub multi_coupon_zk_rate: Option<String>,
pub price_after_multi_coupon: Option<String>,
pub multi_coupon_item_count: Option<String>,
pub lock_rate: Option<String>,
pub lock_rate_end_time: Option<u64>,
pub lock_rate_start_time: Option<u64>,
pub promotion_type: Option<String>,
pub promotion_info: Option<String>,
pub promotion_discount: Option<String>,
pub promotion_condition: Option<String>,
pub presale_discount_fee_text: Option<String>,
pub presale_tail_end_time: Option<u64>,
pub presale_tail_start_time: Option<u64>,
pub presale_end_time: Option<u64>,
pub presale_start_time: Option<u64>,
pub presale_deposit: Option<String>,
pub ysyl_tlj_use_start_time: Option<String>,
pub ysyl_commission_rate: Option<String>,
pub ysyl_tlj_send_time: Option<String>,
pub ysyl_tlj_face: Option<String>,
pub ysyl_click_url: Option<String>,
pub ysyl_tlj_use_end_time: Option<String>,
pub ju_pre_show_end_time: Option<String>,
pub ju_pre_show_start_time: Option<String>,
pub sale_price: Option<String>,
pub kuadian_promotion_info: Option<String>,
pub sub_title: Option<String>,
pub jhs_price_usp_list: Option<String>,
pub tqg_online_end_time: Option<String>,
pub tqg_online_start_time: Option<String>,
pub tqg_sold_count: Option<u64>,
pub tqg_total_count: Option<u64>,
pub superior_brand: Option<String>,
pub is_brand_flash_sale: Option<String>,
pub ju_play_end_time: Option<u64>,
pub ju_play_start_time: Option<u64>,
pub play_info: Option<String>,
pub tmall_play_activity_end_time: Option<u64>,
pub tmall_play_activity_start_time: Option<u64>,
pub level_one_category_id: Option<u64>,
pub uv_sum_pre_sale: Option<u64>,
pub favorites_info: Option<Vec<Favorite>>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct WordData{
pub url: Option<String>,
pub word: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct Favorite{
pub total_count: Option<u64>,
pub favorites_list: Option<Vec<FavoritesDetail>>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct FavoritesDetail{
pub favorites_id: Option<u64>,
pub favorites_title: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbJhsSearchResponse {
pub page_size: Option<u64>,
pub total_item: Option<u64>,
pub total_page: Option<u64>,
pub current_page: Option<u64>,
pub model_list: Option<ModelList>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct ModelList {
pub items: Option<Vec<JhsItem>>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct JhsItem {
pub usp_desc_list: Option<DescList>,
pub item_usp_list: Option<DescList>,
pub price_usp_list: Option<DescList>,
pub wap_url: Option<String>,
pub title: Option<String>,
pub tb_first_cat_id: Option<u64>,
pub orig_price: Option<String>,
pub pic_url_for_p_c: Option<String>,
pub act_price: Option<String>,
pub pic_url_for_w_l: Option<String>,
pub category_name: Option<String>,
pub item_id: Option<u64>,
pub show_end_time: Option<u64>,
pub pc_url: Option<String>,
pub platform_id: Option<u64>,
pub show_start_time: Option<u64>,
pub online_end_time: Option<u64>,
pub ju_id: Option<u64>,
pub online_start_time: Option<u64>,
pub pay_postage: Option<bool>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbItemDetailResponse {
pub n_tbk_item: Option<Vec<ItemSimpleDetail>>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct ItemSimpleDetail {
pub cat_name: Option<String>,
pub num_iid: Option<u64>,
pub title: Option<String>,
pub pict_url: Option<String>,
pub small_images: Option<DescList>,
pub reserve_price: Option<String>,
pub zk_final_price: Option<String>,
pub user_type: Option<u8>,
pub provcity: Option<String>,
pub item_url: Option<String>,
pub seller_id: Option<u64>,
pub volume: Option<u64>,
pub nick: Option<String>,
pub cat_leaf_name: Option<String>,
pub is_prepay: Option<bool>,
pub shop_dsr: Option<u64>,
pub ratesum: Option<u64>,
pub i_rfd_rate: Option<bool>,
pub h_good_rate: Option<bool>,
pub h_pay_rate30: Option<bool>,
pub free_shipment: Option<bool>,
pub material_lib_type: Option<String>,
pub presale_discount_fee_text: Option<String>,
pub presale_tail_end_time: Option<u64>,
pub presale_tail_start_time: Option<u64>,
pub presale_end_time: Option<u64>,
pub presale_start_time: Option<u64>,
pub presale_deposit: Option<String>,
pub ju_play_end_time: Option<u64>,
pub ju_play_start_time: Option<u64>,
pub tmall_play_activity_end_time: Option<u64>,
pub tmall_play_activity_start_time: Option<u64>,
pub ju_online_start_time: Option<String>,
pub play_info: Option<String>,
pub ju_online_end_time: Option<String>,
pub ju_pre_show_start_time: Option<String>,
pub ju_pre_show_end_time: Option<String>,
pub sale_price: Option<String>,
pub kuadian_promotion_info: Option<String>,
pub superior_brand: Option<String>,
}
impl TbItemDetailResponse {
pub fn from_resp(resp: &TaobaoResponse) -> LabradorResult<Self> {
let body = resp.body.to_owned().unwrap_or_default();
let v = serde_json::from_str(&body).unwrap_or(Value::Null);
if let Some(result) = v.get("results") {
serde_json::from_value::<Self>(result.to_owned()).map_err( LabraError::from)
} else {
Err(LabraError::MissingField("返回结果有误,缺少字段。".to_owned()))
}
}
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbCouponDetailResponse {
pub coupon_start_fee: Option<String>,
pub cat_name: Option<String>,
pub coupon_end_time: Option<String>,
pub coupon_start_time: Option<String>,
pub coupon_amount: Option<String>,
pub coupon_remain_count: Option<u64>,
pub coupon_total_count: Option<u64>,
pub coupon_src_scene: Option<u8>,
pub coupon_type: Option<u8>,
pub coupon_activity_id: Option<String>,
}
impl TbCouponDetailResponse{
pub fn from_resp(resp: &TaobaoResponse) -> LabradorResult<Self> {
let body = resp.body.to_owned().unwrap_or_default();
let v = serde_json::from_str(&body).unwrap_or(Value::Null);
if let Some(result) = v.get("results") {
serde_json::from_value::<Self>(result.to_owned()).map_err( LabraError::from)
} else {
Err(LabraError::MissingField("返回结果有误,缺少字段。".to_owned()))
}
}
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbCreateTPwdResponse {
pub model: Option<String>,
pub password_simple: Option<String>,
}
impl TbCreateTPwdResponse{
pub fn from_resp(resp: &TaobaoResponse) -> LabradorResult<Self> {
let body = resp.body.to_owned().unwrap_or_default();
let v = serde_json::from_str(&body).unwrap_or(Value::Null);
if let Some(result) = v.get("data") {
serde_json::from_value::<Self>(result.to_owned()).map_err( LabraError::from)
} else {
Err(LabraError::MissingField("返回结果有误,缺少字段。".to_owned()))
}
}
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbTPwdReportGetResponse {
pub hour_pv: Option<u64>,
pub hour_uv: Option<u64>,
pub uv: Option<u64>,
pub pv: Option<u64>,
}
impl TbTPwdReportGetResponse{
pub fn from_resp(resp: &TaobaoResponse) -> LabradorResult<Self> {
let body = resp.body.to_owned().unwrap_or_default();
let v = serde_json::from_str(&body).unwrap_or(Value::Null);
if let Some(result) = v.get("data") {
serde_json::from_value::<Self>(result.to_owned()).map_err( LabraError::from)
} else {
Err(LabraError::MissingField("返回结果有误,缺少字段。".to_owned()))
}
}
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbSpreadGetResponse {
pub results: Option<Vec<TbkSpread>>,
pub total_results: Option<u64>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbkSpread {
pub content: Option<String>,
pub err_msg: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbGetActivityInfoResponse {
pub wx_qrcode_url: Option<String>,
pub click_url: Option<String>,
pub short_click_url: Option<String>,
pub terminal_type: Option<String>,
pub material_oss_url: Option<String>,
pub page_name: Option<String>,
pub page_start_time: Option<String>,
pub page_end_time: Option<String>,
pub wx_miniprogram_path: Option<String>,
}
impl TbGetActivityInfoResponse{
pub fn from_resp(resp: &TaobaoResponse) -> LabradorResult<Self> {
let body = resp.body.to_owned().unwrap_or_default();
let v = serde_json::from_str(&body).unwrap_or(Value::Null);
if let Some(result) = v.get("data") {
serde_json::from_value::<Self>(result.to_owned()).map_err( LabraError::from)
} else {
Err(LabraError::MissingField("返回结果有误,缺少字段。".to_owned()))
}
}
}
#[derive(Debug, Deserialize,Serialize)]
pub struct TbMaterialSearchResponse {
pub total_results: Option<u64>,
pub result_list: Option<ResultlList<MaterialSearchItem>>,
}
#[derive(Debug, Deserialize,Serialize)]
pub struct MaterialSearchItem {
pub zk_final_price: Option<String>,
pub reserve_price: Option<String>,
pub small_images: Option<DescList>,
pub pict_url: Option<String>,
pub title: Option<String>,
pub coupon_start_time: Option<String>,
pub coupon_end_time: Option<String>,
pub info_dxjh: Option<String>,
pub tk_total_sales: Option<String>,
pub tk_total_commi: Option<String>,
pub coupon_id: Option<String>,
pub num_iid: Option<u64>,
pub user_type: Option<u8>,
pub provcity: Option<String>,
pub item_url: Option<String>,
pub include_mkt: Option<String>,
pub include_dxjh: Option<String>,
pub commission_rate: Option<String>,
pub volume: Option<u64>,
pub seller_id: Option<u64>,
pub coupon_total_count: Option<u64>,
pub coupon_remain_count: Option<u64>,
pub coupon_info: Option<String>,
pub commission_type: Option<String>,
pub shop_title: Option<String>,
pub shop_dsr: Option<u64>,
pub category_id: Option<u64>,
pub jdd_num: Option<u64>,
pub uv_sum_pre_sale: Option<u64>,
pub coupon_share_url: Option<String>,
pub url: Option<String>,
pub level_one_category_name: Option<String>,
pub category_name: Option<String>,
pub short_title: Option<String>,
pub white_image: Option<String>,
pub oetime: Option<String>,
pub ostime: Option<String>,
pub jdd_price: Option<String>,
pub x_id: Option<String>,
pub coupon_start_fee: Option<String>,
pub coupon_amount: Option<String>,
pub item_description: Option<String>,
pub nick: Option<String>,
pub orig_price: Option<String>,
pub tmall_play_activity_info: Option<String>,
pub total_stock: Option<u64>,
pub sell_num: Option<u64>,
pub stock: Option<u64>,
pub item_id: Option<u64>,
pub lock_rate_end_time: Option<u64>,
pub lock_rate_start_time: Option<u64>,
pub real_post_fee: Option<String>,
pub lock_rate: Option<String>,
pub presale_discount_fee_text: Option<String>,
pub presale_tail_end_time: Option<u64>,
pub presale_tail_start_time: Option<u64>,
pub presale_end_time: Option<u64>,
pub presale_start_time: Option<u64>,
pub reward_info: Option<u64>,
pub presale_deposit: Option<String>,
pub ysyl_tlj_use_start_time: Option<String>,
pub ysyl_commission_rate: Option<String>,
pub ysyl_tlj_send_time: Option<String>,
pub ysyl_tlj_face: Option<String>,
pub ysyl_click_url: Option<String>,
pub ysyl_tlj_use_end_time: Option<String>,
pub ju_pre_show_end_time: Option<String>,
pub ju_pre_show_start_time: Option<String>,
pub sale_price: Option<String>,
pub kuadian_promotion_info: Option<String>,
pub sale_begin_time: Option<String>,
pub sale_end_time: Option<String>,
pub distance: Option<String>,
pub usable_shop_id: Option<String>,
pub usable_shop_name: Option<String>,
pub superior_brand: Option<String>,
pub is_brand_flash_sale: Option<String>,
}