use serde::{Deserialize, Serialize};
use serde::de::DeserializeOwned;
use serde_json::{Value as JsonValue};
use crate::{errors::LabraError, LabradorResult, request::Response, RequestMethod};
use crate::jd::constants::ERROR_RESPONSE_KEY;
#[derive(Debug, Serialize, Deserialize)]
pub struct JDResponse {
pub code: Option<String>,
pub message: Option<String>,
pub body: Option<String>,
}
impl JDResponse {
pub fn new() -> Self {
Self {
code: Some("0".to_string()),
message: 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(JDResponse::new());
Err(LabraError::ClientError {errcode: resp.code.to_owned().unwrap_or_default().to_string(), errmsg: resp.message.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(JDResponse::new());
if resp.code.is_none() {
resp.code = "0".to_string().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().eq("0")
}
pub fn get_biz_model<T: DeserializeOwned>(&self, key: Option<&str>) -> LabradorResult<T> {
if self.is_success() {
if let Some(key) = key {
let v = serde_json::from_str::<JsonValue>(&self.body.to_owned().unwrap_or_default())?;
let result = &v[key];
if result.is_string() {
serde_json::from_str::<T>(result.as_str().unwrap_or_default()).map_err(LabraError::from)
} else {
serde_json::from_value::<T>(v[key].to_owned()).map_err(LabraError::from)
}
} else {
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.message.to_owned().unwrap_or_default() })
}
}
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdCommonResponse <T> {
pub message: Option<String>,
pub request_id: Option<String>,
pub has_more: Option<bool>,
pub code: Option<i32>,
pub total_count: Option<u64>,
pub data: Option<T>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdJFGoodsSelect {
pub category_info: Option<JdCategoryInfo>,
pub commission_info: Option<JdCommissionInfo>,
pub coupon_info: Option<JdCouponInfo>,
pub good_comments_share: Option<f64>,
pub comments: Option<u64>,
pub image_info: Option<ImageInfo>,
pub in_order_count30_days: Option<u64>,
pub material_url: Option<String>,
pub price_info: Option<PriceInfo>,
pub shop_info: Option<ShopInfo>,
pub sku_id: Option<u64>,
pub sku_name: Option<String>,
pub spuid: Option<u64>,
pub brand_code: Option<String>,
pub brand_name: Option<String>,
pub owner: Option<String>,
pub pin_gou_info: Option<PinGouInfo>,
pub resource_info: Option<ResourceInfo>,
pub in_order_count30_days_sku: Option<u64>,
pub seckill_info: Option<SeckillInfo>,
pub jx_flags: Option<Vec<u8>>,
pub document_info: Option<DocumentInfo>,
pub book_info: Option<DocumentInfo>,
pub forbid_types: Option<Vec<u32>>,
pub delivery_type: Option<u8>,
pub is_hot: Option<u8>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdCategoryInfo {
pub cid1: Option<u64>,
pub cid2: Option<u64>,
pub cid3: Option<u64>,
pub cid1_name: Option<String>,
pub cid2_name: Option<String>,
pub cid3_name: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentInfo {
pub document: Option<String>,
pub discount: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BookInfo {
pub isbn: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SeckillInfo {
pub seckill_ori_price: Option<String>,
pub seckill_price: Option<String>,
pub seckill_start_time: Option<String>,
pub seckill_end_time: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ResourceInfo {
pub elite_id: Option<u64>,
pub elite_name: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PinGouInfo {
pub pingou_price: Option<f64>,
pub pingou_tm_count: Option<u64>,
pub pingou_url: Option<String>,
pub pingou_start_time: Option<u64>,
pub pingou_end_time: Option<u64>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ShopInfo {
pub shop_name: Option<String>,
pub shop_id: Option<u64>,
pub afs_factor_score_rank_grade: Option<String>,
pub after_service_score: Option<String>,
pub comment_factor_score_rank_grade: Option<String>,
pub logistics_factor_score_rank_grade: Option<String>,
pub logistics_lvyue_score: Option<String>,
pub user_evaluate_score: Option<String>,
pub score_rank_rate: Option<String>,
pub shop_label: Option<String>,
pub shop_level: Option<f64>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PriceInfo {
pub price: Option<f64>,
pub lowest_price: Option<f64>,
pub lowest_price_type: Option<u8>,
pub lowest_coupon_price: Option<f64>,
pub history_price_day: Option<f64>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdCouponInfo {
pub coupon_list: Option<Vec<JdCouponDetail>>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ImageInfo {
pub image_list: Option<Vec<Url>>,
pub white_image: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Url {
pub url: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdCouponDetail {
pub get_end_time: Option<u64>,
pub get_start_time: Option<u64>,
pub quota: Option<f64>,
pub platform_type: Option<u8>,
pub use_end_time: Option<u64>,
pub use_start_time: Option<u64>,
pub bind_type: Option<u8>,
pub is_best: Option<u8>,
pub link: Option<String>,
pub hot_value: Option<u8>,
pub discount: Option<f64>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdCommissionInfo {
pub commission: Option<f64>,
pub commission_share: Option<f64>,
pub coupon_commission: Option<f64>,
pub plus_commission_share: Option<f64>,
pub is_lock: Option<u8>,
pub start_time: Option<u64>,
pub end_time: Option<u64>,
}
impl Response <JdCommonResponse<Vec<JdJFGoodsSelect>>> for JsonValue {
fn parse_result(&self) -> LabradorResult<JdCommonResponse<Vec<JdJFGoodsSelect>>> {
serde_json::from_value::<JdCommonResponse<Vec<JdJFGoodsSelect>>>(self.to_owned()).map_err(LabraError::from)
}
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdGoodsInfoQuery {
pub sku_id: Option<u64>,
pub unit_price: Option<f64>,
pub commision_ratio_wl: Option<f64>,
pub commision_ratio_pc: Option<f64>,
pub wl_unit_price: Option<f64>,
pub material_url: Option<String>,
pub cid2_name: Option<String>,
pub cid_name: Option<String>,
pub cid3_name: Option<String>,
pub img_url: Option<String>,
pub goods_name: Option<String>,
pub plus_commission_share: Option<f64>,
pub is_free_freight_risk: Option<u8>,
pub is_free_shipping: Option<u8>,
pub is_seckill: Option<u8>,
pub is_jd_sale: Option<u8>,
pub end_date: Option<u64>,
pub start_date: Option<u64>,
pub in_order_count: Option<u64>,
pub vid: Option<u64>,
pub cid2: Option<u64>,
pub cid3: Option<u64>,
pub cid: Option<u64>,
pub shop_id: Option<u64>,
}
impl Response <JdCommonResponse<Vec<JdGoodsInfoQuery>>> for JsonValue {
fn parse_result(&self) -> LabradorResult<JdCommonResponse<Vec<JdGoodsInfoQuery>>> {
serde_json::from_value::<JdCommonResponse<Vec<JdGoodsInfoQuery>>>(self.to_owned()).map_err(LabraError::from)
}
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdPromotionUrlGenerateResponse{
pub click_u_r_l: Option<String>,
}
impl Response <JdCommonResponse<JdPromotionUrlGenerateResponse>> for JsonValue {
fn parse_result(&self) -> LabradorResult<JdCommonResponse<JdPromotionUrlGenerateResponse>> {
serde_json::from_value::<JdCommonResponse<JdPromotionUrlGenerateResponse>>(self.to_owned()).map_err(LabraError::from)
}
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdOrderQueryResponse {
pub order_row_resp: Option<Vec<JdOrderQueryResp>>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdOrderQueryResp{
pub finish_time: Option<u64>,
pub order_emt: Option<u8>,
pub plus: Option<u8>,
pub order_id: Option<u64>,
pub order_time: Option<u64>,
pub parent_id: Option<u64>,
pub union_id: Option<u64>,
pub pop_id: Option<u64>,
pub pay_month: Option<String>,
pub ext1: Option<String>,
pub valid_code: Option<u8>,
pub sku_list: Option<SkuInfo>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SkuInfo{
pub actual_cos_price: Option<f64>,
pub actual_fee: Option<f64>,
pub commission_rate: Option<f64>,
pub estimate_cos_price: Option<f64>,
pub estimate_fee: Option<f64>,
pub final_rate: Option<f64>,
pub price: Option<f64>,
pub cid1: Option<u64>,
pub frozen_sku_num: Option<u64>,
pub position_id: Option<u64>,
pub cid2: Option<u64>,
pub site_id: Option<u64>,
pub sku_id: Option<u64>,
pub sku_num: Option<u64>,
pub sku_return_num: Option<u64>,
pub sub_side_rate: Option<u64>,
pub subsidy_rate: Option<u64>,
pub cid3: Option<u64>,
pub pid: Option<String>,
pub sku_name: Option<String>,
pub union_alias: Option<String>,
pub union_tag: Option<String>,
pub union_traffic_group: Option<u8>,
pub valid_code: Option<u64>,
pub sub_union_id: Option<String>,
pub trace_type: Option<u8>,
pub pay_month: Option<u64>,
pub pop_id: Option<u64>,
pub cp_act_id: Option<u64>,
pub union_role: Option<u8>,
pub gift_coupon_ocs_amount: Option<u64>,
pub pro_price_amount: Option<f64>,
pub ext1: Option<String>,
pub gift_coupon_key: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdPromotionCodeGetResponse{
pub short_u_r_l: Option<String>,
pub click_u_r_l: Option<String>,
pub j_command: Option<String>,
pub j_short_command: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct JdPromotionBySubUnionIdGetResponse {
pub short_u_r_l: Option<String>,
pub click_u_r_l: Option<String>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PromotionCode {
pub promo_name: Option<String>,
pub promo_code: Option<String>,
pub begin_time: Option<u64>,
pub end_time: Option<u64>,
pub total_cnt: Option<u64>,
pub promo_type: Option<u8>,
pub state: Option<u8>,
pub direct_reduce_amount: Option<u8>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SellingGoodsQueryShopInfo {
pub shop_name: Option<String>,
pub shop_type: Option<u8>,
}
#[derive(Debug, Deserialize,Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SellingGoodsQueryResponse {
pub sku_id: Option<u64>,
pub sku_name: Option<String>,
pub material_url: Option<String>,
pub owner: Option<String>,
pub image_url: Option<String>,
pub img_list: Option<Vec<String>>,
pub cid1: Option<u64>,
pub cid2: Option<u64>,
pub cid3: Option<u64>,
pub cid1_name: Option<String>,
pub cid2_name: Option<String>,
pub cid3_name: Option<String>,
pub in_order_count30_days: Option<u64>,
pub goods_comments: Option<u64>,
pub wl_price: Option<f64>,
pub lowest_price: Option<f64>,
pub wl_commission_share: Option<f64>,
pub wl_commission: Option<f64>,
pub coupon_list: Option<Vec<JdCouponDetail>>,
pub shop_info: Option<ShopInfo>,
pub promotion_code_list: Option<Vec<PromotionCode>>,
pub currency: Option<String>,
}