ztk_rust_sdk/jd/
response.rs

1//! 京东平台响应结构体
2//!
3//! 定义京东平台 API 的响应结构体
4
5use serde::Deserialize;
6
7/// 京东转链响应
8///
9/// convert 接口的响应
10#[derive(Debug, Clone, Deserialize)]
11pub struct JdConvertResponse {
12    /// 状态码,200 表示成功
13    #[serde(default)]
14    pub status: i32,
15    /// 转链结果数据
16    #[serde(default)]
17    pub content: Option<Vec<JdConvertResult>>,
18}
19
20/// 京东转链结果
21#[derive(Debug, Clone, Deserialize)]
22pub struct JdConvertResult {
23    /// 折淘客编号
24    #[serde(default)]
25    pub code: Option<String>,
26    /// 分类 ID
27    #[serde(default)]
28    pub type_one_id: Option<String>,
29    /// 商品 ID (SKU)
30    #[serde(default)]
31    pub tao_id: Option<String>,
32    /// 商品短标题
33    #[serde(default)]
34    pub title: Option<String>,
35    /// 商品简介
36    #[serde(default)]
37    pub jianjie: Option<String>,
38    /// 商品主图
39    #[serde(default)]
40    pub pict_url: Option<String>,
41    /// 是否京东自营: 0-非自营, 1-自营
42    #[serde(default)]
43    pub user_type: Option<String>,
44    /// 卖家 ID
45    #[serde(default)]
46    pub seller_id: Option<String>,
47    /// 商品描述分
48    #[serde(default)]
49    pub shop_dsr: Option<String>,
50    /// 年销量
51    #[serde(default)]
52    pub volume: Option<String>,
53    /// 折扣价
54    #[serde(default)]
55    pub size: Option<String>,
56    /// 券后价
57    #[serde(default)]
58    pub quanhou_jiage: Option<String>,
59    /// 佣金比率
60    #[serde(default)]
61    pub tkrate3: Option<String>,
62    /// 佣金类型
63    #[serde(default)]
64    pub yongjin_type: Option<String>,
65    /// 优惠券 ID
66    #[serde(default)]
67    pub coupon_id: Option<String>,
68    /// 优惠券开始时间
69    #[serde(default)]
70    pub coupon_start_time: Option<String>,
71    /// 优惠券结束时间
72    #[serde(default)]
73    pub coupon_end_time: Option<String>,
74    /// 优惠券金额
75    #[serde(default)]
76    pub coupon_info_money: Option<String>,
77    /// 优惠券总数量
78    #[serde(default)]
79    pub coupon_total_count: Option<String>,
80    /// 优惠券剩余数量
81    #[serde(default)]
82    pub coupon_remain_count: Option<String>,
83    /// 优惠券信息
84    #[serde(default)]
85    pub coupon_info: Option<String>,
86    /// 是否京东配送: 1-是
87    #[serde(default)]
88    pub juhuasuan: Option<String>,
89    /// 是否京东拼购: 1-是
90    #[serde(default)]
91    pub taoqianggou: Option<String>,
92    /// 是否海淘 (京东国际): 1-是
93    #[serde(default)]
94    pub haitao: Option<String>,
95    /// 是否京喜商品: 1-是
96    #[serde(default)]
97    pub jiyoujia: Option<String>,
98    /// 是否京东好店: 1-是
99    #[serde(default)]
100    pub jinpaimaijia: Option<String>,
101    /// 是否精选品牌: 1-是
102    #[serde(default)]
103    pub pinpai: Option<String>,
104    /// 品牌名称
105    #[serde(default)]
106    pub pinpai_name: Option<String>,
107    /// 是否有运费险: 1-有
108    #[serde(default)]
109    pub yunfeixian: Option<String>,
110    /// 卖家昵称
111    #[serde(default)]
112    pub nick: Option<String>,
113    /// 商品小图列表 (用 | 分隔)
114    #[serde(default)]
115    pub small_images: Option<String>,
116    /// 商品白底图
117    #[serde(default)]
118    pub white_image: Option<String>,
119    /// 商品长标题
120    #[serde(default)]
121    pub tao_title: Option<String>,
122    /// 宝贝所在地
123    #[serde(default)]
124    pub provcity: Option<String>,
125    /// 店铺名称
126    #[serde(default)]
127    pub shop_title: Option<String>,
128    /// 视频地址
129    #[serde(default)]
130    pub zhibo_url: Option<String>,
131    /// 实时总销量
132    #[serde(default, rename = "sellCount")]
133    pub sell_count: Option<String>,
134    /// 评论数量
135    #[serde(default, rename = "commentCount")]
136    pub comment_count: Option<String>,
137    /// 收藏数量
138    #[serde(default)]
139    pub favcount: Option<String>,
140    /// 宝贝描述分
141    #[serde(default)]
142    pub score1: Option<String>,
143    /// 卖家服务分
144    #[serde(default)]
145    pub score2: Option<String>,
146    /// 物流服务分
147    #[serde(default)]
148    pub score3: Option<String>,
149    /// 店铺等级 (1-20)
150    #[serde(default, rename = "creditLevel")]
151    pub credit_level: Option<String>,
152    /// 店铺 logo
153    #[serde(default, rename = "shopIcon")]
154    pub shop_icon: Option<String>,
155    /// 图文详情图片地址 (用 | 分隔)
156    #[serde(default, rename = "pcDescContent")]
157    pub pc_desc_content: Option<String>,
158    /// 商品 URL
159    #[serde(default)]
160    pub item_url: Option<String>,
161    /// 叶子类目 ID
162    #[serde(default)]
163    pub category_id: Option<String>,
164    /// 叶子类目名称
165    #[serde(default)]
166    pub category_name: Option<String>,
167    /// 一级类目 ID
168    #[serde(default)]
169    pub level_one_category_id: Option<String>,
170    /// 一级类目名称
171    #[serde(default)]
172    pub level_one_category_name: Option<String>,
173    /// 返佣金额
174    #[serde(default)]
175    pub tkfee3: Option<String>,
176    /// 朋友圈文案
177    #[serde(default)]
178    pub tag: Option<String>,
179    /// 数据添加时间
180    #[serde(default)]
181    pub date_time: Option<String>,
182    /// 二合一推广链接
183    #[serde(default)]
184    pub coupon_click_url: Option<String>,
185    /// 推广短链接
186    #[serde(default)]
187    pub shorturl: Option<String>,
188}
189
190/// 京粉精选商品响应
191///
192/// jingfen_goods 接口的响应
193#[derive(Debug, Clone, Deserialize)]
194pub struct JingfenGoodsResponse {
195    /// 京东联盟响应
196    #[serde(default, rename = "jd_union_open_goods_jingfen_query_response")]
197    pub response: Option<JingfenQueryResponse>,
198}
199
200/// 京粉查询响应
201#[derive(Debug, Clone, Deserialize)]
202pub struct JingfenQueryResponse {
203    /// 查询结果
204    #[serde(default, rename = "queryResult")]
205    pub query_result: Option<JingfenQueryResult>,
206}
207
208/// 京粉查询结果
209#[derive(Debug, Clone, Deserialize)]
210pub struct JingfenQueryResult {
211    /// 状态码
212    #[serde(default)]
213    pub code: Option<String>,
214    /// 消息
215    #[serde(default)]
216    pub message: Option<String>,
217    /// 商品列表
218    #[serde(default)]
219    pub data: Option<Vec<JingfenGoodsItem>>,
220    /// 总数量
221    #[serde(default, rename = "totalCount")]
222    pub total_count: Option<i64>,
223}
224
225/// 京粉商品项
226#[derive(Debug, Clone, Deserialize)]
227pub struct JingfenGoodsItem {
228    /// 商品 SKU ID
229    #[serde(default, rename = "skuId")]
230    pub sku_id: Option<i64>,
231    /// 商品名称
232    #[serde(default, rename = "skuName")]
233    pub sku_name: Option<String>,
234    /// 商品落地页
235    #[serde(default, rename = "materialUrl")]
236    pub material_url: Option<String>,
237    /// 商品主图
238    #[serde(default, rename = "imageInfo")]
239    pub image_info: Option<JdImageInfo>,
240    /// 价格信息
241    #[serde(default, rename = "priceInfo")]
242    pub price_info: Option<JdPriceInfo>,
243    /// 佣金信息
244    #[serde(default, rename = "commissionInfo")]
245    pub commission_info: Option<JdCommissionInfo>,
246    /// 优惠券信息
247    #[serde(default, rename = "couponInfo")]
248    pub coupon_info: Option<JdCouponInfo>,
249    /// 店铺信息
250    #[serde(default, rename = "shopInfo")]
251    pub shop_info: Option<JdShopInfo>,
252    /// 分类信息
253    #[serde(default, rename = "categoryInfo")]
254    pub category_info: Option<JdCategoryInfo>,
255    /// 拼购信息
256    #[serde(default, rename = "pinGouInfo")]
257    pub pingou_info: Option<JdPingouInfo>,
258    /// 30天引单量
259    #[serde(default, rename = "inOrderCount30Days")]
260    pub in_order_count_30_days: Option<i64>,
261    /// 30天引单金额
262    #[serde(default, rename = "inOrderComm30Days")]
263    pub in_order_comm_30_days: Option<f64>,
264    /// 评论数
265    #[serde(default)]
266    pub comments: Option<i64>,
267    /// 好评率
268    #[serde(default, rename = "goodCommentsShare")]
269    pub good_comments_share: Option<f64>,
270    /// 品牌编码
271    #[serde(default, rename = "brandCode")]
272    pub brand_code: Option<String>,
273    /// 品牌名称
274    #[serde(default, rename = "brandName")]
275    pub brand_name: Option<String>,
276    /// 店铺性质: g-自营, p-pop
277    #[serde(default)]
278    pub owner: Option<String>,
279    /// 是否京东自营
280    #[serde(default, rename = "isJdSale")]
281    pub is_jd_sale: Option<i32>,
282}
283
284/// 京东图片信息
285#[derive(Debug, Clone, Deserialize)]
286pub struct JdImageInfo {
287    /// 图片列表
288    #[serde(default, rename = "imageList")]
289    pub image_list: Option<Vec<JdImage>>,
290    /// 白底图
291    #[serde(default, rename = "whiteImage")]
292    pub white_image: Option<String>,
293}
294
295/// 京东图片
296#[derive(Debug, Clone, Deserialize)]
297pub struct JdImage {
298    /// 图片 URL
299    #[serde(default)]
300    pub url: Option<String>,
301}
302
303/// 京东价格信息
304#[derive(Debug, Clone, Deserialize)]
305pub struct JdPriceInfo {
306    /// 商品价格
307    #[serde(default)]
308    pub price: Option<f64>,
309    /// 最低价格
310    #[serde(default, rename = "lowestPrice")]
311    pub lowest_price: Option<f64>,
312    /// 最低券后价
313    #[serde(default, rename = "lowestCouponPrice")]
314    pub lowest_coupon_price: Option<f64>,
315    /// 历史最低价
316    #[serde(default, rename = "historyPriceDay")]
317    pub history_price_day: Option<i32>,
318}
319
320/// 京东佣金信息
321#[derive(Debug, Clone, Deserialize)]
322pub struct JdCommissionInfo {
323    /// 佣金
324    #[serde(default)]
325    pub commission: Option<f64>,
326    /// 佣金比例
327    #[serde(default, rename = "commissionShare")]
328    pub commission_share: Option<f64>,
329    /// 券后佣金比例
330    #[serde(default, rename = "couponCommission")]
331    pub coupon_commission: Option<f64>,
332    /// 加入计划佣金比例
333    #[serde(default, rename = "plusCommissionShare")]
334    pub plus_commission_share: Option<f64>,
335}
336
337/// 京东优惠券信息
338#[derive(Debug, Clone, Deserialize)]
339pub struct JdCouponInfo {
340    /// 优惠券列表
341    #[serde(default, rename = "couponList")]
342    pub coupon_list: Option<Vec<JdCoupon>>,
343}
344
345/// 京东优惠券
346#[derive(Debug, Clone, Deserialize)]
347pub struct JdCoupon {
348    /// 券类型: 1-平台券, 2-店铺券
349    #[serde(default, rename = "bindType")]
350    pub bind_type: Option<i32>,
351    /// 优惠券面额
352    #[serde(default)]
353    pub discount: Option<f64>,
354    /// 优惠券链接
355    #[serde(default)]
356    pub link: Option<String>,
357    /// 券使用平台: 0-全平台, 1-限平台券, 2-限移动端
358    #[serde(default, rename = "platformType")]
359    pub platform_type: Option<i32>,
360    /// 券消费限额
361    #[serde(default)]
362    pub quota: Option<f64>,
363    /// 券开始时间
364    #[serde(default, rename = "getStartTime")]
365    pub get_start_time: Option<i64>,
366    /// 券结束时间
367    #[serde(default, rename = "getEndTime")]
368    pub get_end_time: Option<i64>,
369    /// 是否最优券
370    #[serde(default, rename = "isBest")]
371    pub is_best: Option<i32>,
372}
373
374/// 京东店铺信息
375#[derive(Debug, Clone, Deserialize)]
376pub struct JdShopInfo {
377    /// 店铺 ID
378    #[serde(default, rename = "shopId")]
379    pub shop_id: Option<i64>,
380    /// 店铺名称
381    #[serde(default, rename = "shopName")]
382    pub shop_name: Option<String>,
383    /// 店铺等级
384    #[serde(default, rename = "shopLevel")]
385    pub shop_level: Option<f64>,
386    /// 店铺评分
387    #[serde(default, rename = "shopLabel")]
388    pub shop_label: Option<String>,
389}
390
391/// 京东分类信息
392#[derive(Debug, Clone, Deserialize)]
393pub struct JdCategoryInfo {
394    /// 一级类目 ID
395    #[serde(default)]
396    pub cid1: Option<i64>,
397    /// 一级类目名称
398    #[serde(default, rename = "cid1Name")]
399    pub cid1_name: Option<String>,
400    /// 二级类目 ID
401    #[serde(default)]
402    pub cid2: Option<i64>,
403    /// 二级类目名称
404    #[serde(default, rename = "cid2Name")]
405    pub cid2_name: Option<String>,
406    /// 三级类目 ID
407    #[serde(default)]
408    pub cid3: Option<i64>,
409    /// 三级类目名称
410    #[serde(default, rename = "cid3Name")]
411    pub cid3_name: Option<String>,
412}
413
414/// 京东拼购信息
415#[derive(Debug, Clone, Deserialize)]
416pub struct JdPingouInfo {
417    /// 拼购价格
418    #[serde(default, rename = "pingouPrice")]
419    pub pingou_price: Option<f64>,
420    /// 拼购成团人数
421    #[serde(default, rename = "pingouTmCount")]
422    pub pingou_tm_count: Option<i64>,
423    /// 拼购链接
424    #[serde(default, rename = "pingouUrl")]
425    pub pingou_url: Option<String>,
426    /// 拼购开始时间
427    #[serde(default, rename = "pingouStartTime")]
428    pub pingou_start_time: Option<i64>,
429    /// 拼购结束时间
430    #[serde(default, rename = "pingouEndTime")]
431    pub pingou_end_time: Option<i64>,
432}
433
434/// 京东订单查询响应
435///
436/// query_orders 接口的响应
437#[derive(Debug, Clone, Deserialize)]
438pub struct JdOrderResponse {
439    /// 状态码,200 表示成功
440    #[serde(default)]
441    pub status: i32,
442    /// 订单数据
443    #[serde(default)]
444    pub data: Option<JdOrderData>,
445}
446
447/// 京东订单数据
448#[derive(Debug, Clone, Deserialize)]
449pub struct JdOrderData {
450    /// 是否有下一页
451    #[serde(default)]
452    pub has_more: Option<bool>,
453    /// 订单列表
454    #[serde(default)]
455    pub data: Option<Vec<JdOrderInfo>>,
456}
457
458/// 京东订单信息
459#[derive(Debug, Clone, Deserialize)]
460pub struct JdOrderInfo {
461    /// 订单号
462    #[serde(default, rename = "orderId")]
463    pub order_id: Option<i64>,
464    /// 父订单号
465    #[serde(default, rename = "parentId")]
466    pub parent_id: Option<i64>,
467    /// 下单时间
468    #[serde(default, rename = "orderTime")]
469    pub order_time: Option<String>,
470    /// 完成时间
471    #[serde(default, rename = "finishTime")]
472    pub finish_time: Option<String>,
473    /// 更新时间
474    #[serde(default, rename = "modifyTime")]
475    pub modify_time: Option<String>,
476    /// 订单状态: 1-待付款, 2-已付款, 3-已完成, 4-已取消
477    #[serde(default, rename = "validCode")]
478    pub valid_code: Option<i32>,
479    /// 商品 SKU ID
480    #[serde(default, rename = "skuId")]
481    pub sku_id: Option<i64>,
482    /// 商品名称
483    #[serde(default, rename = "skuName")]
484    pub sku_name: Option<String>,
485    /// 商品数量
486    #[serde(default, rename = "skuNum")]
487    pub sku_num: Option<i32>,
488    /// 商品单价
489    #[serde(default)]
490    pub price: Option<f64>,
491    /// 实际支付金额
492    #[serde(default, rename = "actualCosPrice")]
493    pub actual_cos_price: Option<f64>,
494    /// 实际佣金
495    #[serde(default, rename = "actualFee")]
496    pub actual_fee: Option<f64>,
497    /// 预估佣金
498    #[serde(default, rename = "estimateCosPrice")]
499    pub estimate_cos_price: Option<f64>,
500    /// 预估佣金金额
501    #[serde(default, rename = "estimateFee")]
502    pub estimate_fee: Option<f64>,
503    /// 佣金比例
504    #[serde(default, rename = "commissionRate")]
505    pub commission_rate: Option<f64>,
506    /// 子渠道标识
507    #[serde(default, rename = "subUnionId")]
508    pub sub_union_id: Option<String>,
509    /// 推广位 ID
510    #[serde(default, rename = "positionId")]
511    pub position_id: Option<i64>,
512    /// 站点 ID
513    #[serde(default, rename = "siteId")]
514    pub site_id: Option<i64>,
515    /// 联盟 ID
516    #[serde(default, rename = "unionId")]
517    pub union_id: Option<i64>,
518    /// 一级类目 ID
519    #[serde(default)]
520    pub cid1: Option<i64>,
521    /// 二级类目 ID
522    #[serde(default)]
523    pub cid2: Option<i64>,
524    /// 三级类目 ID
525    #[serde(default)]
526    pub cid3: Option<i64>,
527    /// 是否 plus 会员
528    #[serde(default)]
529    pub plus: Option<i32>,
530}
531
532/// 京东商品详情响应
533///
534/// goods_detail 接口的响应
535#[derive(Debug, Clone, Deserialize)]
536pub struct JdGoodsDetailResponse {
537    /// 状态码,200 表示成功
538    #[serde(default)]
539    pub status: i32,
540    /// 商品详情列表
541    #[serde(default)]
542    pub data: Option<Vec<JingfenGoodsItem>>,
543}
544
545/// 京东朋友圈火爆商品响应
546///
547/// hot_goods 接口的响应
548#[derive(Debug, Clone, Deserialize)]
549pub struct JdHotGoodsResponse {
550    /// 状态码,200 表示成功
551    #[serde(default)]
552    pub status: i32,
553    /// 商品列表
554    #[serde(default)]
555    pub content: Option<Vec<JdHotGoodsItem>>,
556}
557
558/// 京东朋友圈火爆商品项
559#[derive(Debug, Clone, Deserialize)]
560pub struct JdHotGoodsItem {
561    /// 商品 ID
562    #[serde(default)]
563    pub goods_id: Option<i64>,
564    /// 商品状态: 1-正常, 2-下架
565    #[serde(default)]
566    pub state: Option<i32>,
567    /// 京东商品状态: 2-正常
568    #[serde(default, rename = "J_state")]
569    pub j_state: Option<i32>,
570    /// 商品精编标题
571    #[serde(default)]
572    pub short_name: Option<String>,
573    /// 商品一级类目
574    #[serde(default)]
575    pub goods_type: Option<i32>,
576    /// 商品主图
577    #[serde(default)]
578    pub goods_img: Option<String>,
579    /// 商品原价
580    #[serde(default)]
581    pub goods_price: Option<f64>,
582    /// 商品券后价
583    #[serde(default)]
584    pub discount_price_after: Option<f64>,
585    /// 推荐理由
586    #[serde(default)]
587    pub goods_recommend: Option<String>,
588    /// 商品佣金比例
589    #[serde(default)]
590    pub commissionshare: Option<f64>,
591    /// 商品落地页
592    #[serde(default)]
593    pub goods_link: Option<String>,
594    /// 优惠券面额
595    #[serde(default)]
596    pub discount_price: Option<f64>,
597    /// 领券链接
598    #[serde(default)]
599    pub discount_link: Option<String>,
600    /// 今日领券数
601    #[serde(default)]
602    pub today_num: Option<i32>,
603    /// 券消费限额
604    #[serde(default)]
605    pub quota: Option<f64>,
606    /// 券开始时间
607    #[serde(default)]
608    pub discount_start: Option<String>,
609    /// 券结束时间
610    #[serde(default)]
611    pub discount_end: Option<String>,
612    /// 店铺 ID
613    #[serde(default)]
614    pub shop_id: Option<i64>,
615    /// 店铺名称
616    #[serde(default)]
617    pub shop_name: Option<String>,
618    /// 近30天引入单量
619    #[serde(default, rename = "inOrderCount30Days")]
620    pub in_order_count_30_days: Option<i64>,
621    /// 京东图片合集
622    #[serde(default, rename = "imageList")]
623    pub image_list: Option<String>,
624    /// 商品细节图
625    #[serde(default)]
626    pub img_info: Option<String>,
627    /// 商品更新时间
628    #[serde(default)]
629    pub update_time: Option<String>,
630    /// 品牌 ID
631    #[serde(default)]
632    pub brand_id: Option<String>,
633    /// 京东品牌 code
634    #[serde(default, rename = "brandCode")]
635    pub brand_code: Option<String>,
636    /// 京东品牌名称
637    #[serde(default, rename = "brandName")]
638    pub brand_name: Option<String>,
639    /// 店铺性质: g-自营, p-pop
640    #[serde(default)]
641    pub owner: Option<String>,
642    /// 京东一级类目 ID
643    #[serde(default)]
644    pub cid1: Option<i64>,
645    /// 京东一级类目名称
646    #[serde(default, rename = "cid1Name")]
647    pub cid1_name: Option<String>,
648    /// 京东二级类目 ID
649    #[serde(default)]
650    pub cid2: Option<i64>,
651    /// 京东二级类目名称
652    #[serde(default, rename = "cid2Name")]
653    pub cid2_name: Option<String>,
654    /// 京东三级类目 ID
655    #[serde(default)]
656    pub cid3: Option<i64>,
657    /// 京东三级类目名称
658    #[serde(default, rename = "cid3Name")]
659    pub cid3_name: Option<String>,
660}
661
662#[cfg(test)]
663mod tests {
664    use super::*;
665
666    #[test]
667    fn test_jd_convert_response_deserialize() {
668        let json = r#"{
669            "status": 200,
670            "content": [{
671                "tao_id": "10025768652616",
672                "title": "测试商品",
673                "quanhou_jiage": "99.00",
674                "coupon_click_url": "https://union-click.jd.com/xxx",
675                "shorturl": "https://u.jd.com/xxx"
676            }]
677        }"#;
678
679        let response: JdConvertResponse = serde_json::from_str(json).unwrap();
680        assert_eq!(response.status, 200);
681        assert!(response.content.is_some());
682        let content = response.content.unwrap();
683        assert_eq!(content.len(), 1);
684        assert_eq!(content[0].tao_id, Some("10025768652616".to_string()));
685        assert_eq!(content[0].title, Some("测试商品".to_string()));
686    }
687
688    #[test]
689    fn test_jingfen_goods_response_deserialize() {
690        let json = r#"{
691            "jd_union_open_goods_jingfen_query_response": {
692                "queryResult": {
693                    "code": "200",
694                    "message": "success",
695                    "data": [{
696                        "skuId": 10025768652616,
697                        "skuName": "测试商品",
698                        "inOrderCount30Days": 100
699                    }],
700                    "totalCount": 1
701                }
702            }
703        }"#;
704
705        let response: JingfenGoodsResponse = serde_json::from_str(json).unwrap();
706        assert!(response.response.is_some());
707        let query_response = response.response.unwrap();
708        assert!(query_response.query_result.is_some());
709        let result = query_response.query_result.unwrap();
710        assert_eq!(result.code, Some("200".to_string()));
711        assert!(result.data.is_some());
712        let data = result.data.unwrap();
713        assert_eq!(data.len(), 1);
714        assert_eq!(data[0].sku_id, Some(10025768652616));
715    }
716
717    #[test]
718    fn test_jd_order_response_deserialize() {
719        let json = r#"{
720            "status": 200,
721            "data": {
722                "has_more": true,
723                "data": [{
724                    "orderId": 123456789,
725                    "skuId": 10025768652616,
726                    "skuName": "测试商品",
727                    "validCode": 2,
728                    "price": 99.00,
729                    "actualFee": 9.90
730                }]
731            }
732        }"#;
733
734        let response: JdOrderResponse = serde_json::from_str(json).unwrap();
735        assert_eq!(response.status, 200);
736        assert!(response.data.is_some());
737        let data = response.data.unwrap();
738        assert_eq!(data.has_more, Some(true));
739        assert!(data.data.is_some());
740        let orders = data.data.unwrap();
741        assert_eq!(orders.len(), 1);
742        assert_eq!(orders[0].order_id, Some(123456789));
743    }
744
745    #[test]
746    fn test_jd_hot_goods_response_deserialize() {
747        let json = r#"{
748            "status": 200,
749            "content": [{
750                "goods_id": 10025768652616,
751                "short_name": "测试商品",
752                "goods_price": 99.00,
753                "discount_price_after": 79.00,
754                "commissionshare": 20.0,
755                "shop_name": "测试店铺"
756            }]
757        }"#;
758
759        let response: JdHotGoodsResponse = serde_json::from_str(json).unwrap();
760        assert_eq!(response.status, 200);
761        assert!(response.content.is_some());
762        let content = response.content.unwrap();
763        assert_eq!(content.len(), 1);
764        assert_eq!(content[0].goods_id, Some(10025768652616));
765        assert_eq!(content[0].short_name, Some("测试商品".to_string()));
766    }
767
768    #[test]
769    fn test_response_with_missing_fields() {
770        let json = r#"{"status": 200}"#;
771
772        let response: JdConvertResponse = serde_json::from_str(json).unwrap();
773        assert_eq!(response.status, 200);
774        assert!(response.content.is_none());
775    }
776
777    #[test]
778    fn test_jd_price_info_deserialize() {
779        let json = r#"{
780            "price": 99.00,
781            "lowestPrice": 89.00,
782            "lowestCouponPrice": 79.00
783        }"#;
784
785        let price_info: JdPriceInfo = serde_json::from_str(json).unwrap();
786        assert_eq!(price_info.price, Some(99.00));
787        assert_eq!(price_info.lowest_price, Some(89.00));
788        assert_eq!(price_info.lowest_coupon_price, Some(79.00));
789    }
790
791    #[test]
792    fn test_jd_commission_info_deserialize() {
793        let json = r#"{
794            "commission": 9.90,
795            "commissionShare": 10.0
796        }"#;
797
798        let commission_info: JdCommissionInfo = serde_json::from_str(json).unwrap();
799        assert_eq!(commission_info.commission, Some(9.90));
800        assert_eq!(commission_info.commission_share, Some(10.0));
801    }
802}