ztk-rust-sdk 0.1.1

折淘客 (ZheTaoKe/ZTK) Rust SDK - 多平台电商 API 客户端库
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
//! 拼多多平台响应结构体
//!
//! 定义拼多多平台 API 的响应结构体

use serde::Deserialize;

/// 拼多多转链响应
///
/// convert 接口的响应
#[derive(Debug, Clone, Deserialize)]
pub struct PddConvertResponse {
    /// 转链结果
    #[serde(default, rename = "goods_zs_unit_generate_response")]
    pub response: Option<PddConvertResult>,
}

/// 拼多多转链结果
#[derive(Debug, Clone, Deserialize)]
pub struct PddConvertResult {
    /// 推广短链接 (唤起拼多多 APP)
    #[serde(default)]
    pub multi_group_mobile_short_url: Option<String>,
    /// 双人团推广长链接
    #[serde(default)]
    pub multi_group_url: Option<String>,
    /// 普通长链,微信环境下进入领券页点领券拉起小程序
    #[serde(default)]
    pub mobile_url: Option<String>,
    /// 双人团推广短链接
    #[serde(default)]
    pub multi_group_short_url: Option<String>,
    /// 对应 mobile_url 的短链接
    #[serde(default)]
    pub mobile_short_url: Option<String>,
    /// 推广长链接 (可唤起拼多多 APP)
    #[serde(default)]
    pub multi_group_mobile_url: Option<String>,
    /// 请求 ID
    #[serde(default)]
    pub request_id: Option<String>,
    /// 普通长链,微信环境下优先拉起微信小程序
    #[serde(default)]
    pub url: Option<String>,
    /// 对应 url 的短链接
    #[serde(default)]
    pub short_url: Option<String>,
}

/// 拼多多商品详情响应 (简版)
///
/// goods_detail_simple 接口的响应
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsDetailSimpleResponse {
    /// 商品详情结果
    #[serde(default, rename = "goods_basic_detail_response")]
    pub response: Option<PddGoodsBasicDetailResult>,
}

/// 拼多多商品基本详情结果
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsBasicDetailResult {
    /// 商品列表
    #[serde(default)]
    pub goods_list: Option<Vec<PddGoodsBasicItem>>,
    /// 请求 ID
    #[serde(default)]
    pub request_id: Option<String>,
}

/// 拼多多商品基本信息
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsBasicItem {
    /// 商品名称
    #[serde(default)]
    pub goods_name: Option<String>,
    /// 商品主图
    #[serde(default)]
    pub goods_pic: Option<String>,
    /// 商品原价 (单位: 分)
    #[serde(default)]
    pub min_normal_price: Option<i64>,
    /// 商品 ID
    #[serde(default)]
    pub goods_id: Option<i64>,
    /// 拼团价 (单位: 分)
    #[serde(default)]
    pub min_group_price: Option<i64>,
}

/// 拼多多商品详情响应 (详版)
///
/// goods_detail_full 接口的响应
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsDetailFullResponse {
    /// 商品详情结果
    #[serde(default, rename = "goods_search_response")]
    pub response: Option<PddGoodsSearchResult>,
}

/// 拼多多商品搜索结果
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsSearchResult {
    /// 商品列表
    #[serde(default)]
    pub goods_list: Option<Vec<PddGoodsDetailItem>>,
    /// 请求 ID
    #[serde(default)]
    pub request_id: Option<String>,
    /// 总数量
    #[serde(default)]
    pub total_count: Option<i64>,
}

/// 拼多多商品详细信息
#[derive(Debug, Clone, Deserialize)]
pub struct PddGoodsDetailItem {
    /// 商品 ID
    #[serde(default)]
    pub goods_id: Option<i64>,
    /// 商品名称
    #[serde(default)]
    pub goods_name: Option<String>,
    /// 商品描述
    #[serde(default)]
    pub goods_desc: Option<String>,
    /// 商品主图
    #[serde(default)]
    pub goods_thumbnail_url: Option<String>,
    /// 商品轮播图
    #[serde(default)]
    pub goods_image_url: Option<String>,
    /// 商品详情图列表
    #[serde(default)]
    pub goods_gallery_urls: Option<Vec<String>>,
    /// 商品原价 (单位: 分)
    #[serde(default)]
    pub min_normal_price: Option<i64>,
    /// 拼团价 (单位: 分)
    #[serde(default)]
    pub min_group_price: Option<i64>,
    /// 已售数量
    #[serde(default)]
    pub sales_tip: Option<String>,
    /// 佣金比例 (千分比)
    #[serde(default)]
    pub promotion_rate: Option<i64>,
    /// 优惠券面额 (单位: 分)
    #[serde(default)]
    pub coupon_discount: Option<i64>,
    /// 优惠券门槛 (单位: 分)
    #[serde(default)]
    pub coupon_min_order_amount: Option<i64>,
    /// 优惠券剩余数量
    #[serde(default)]
    pub coupon_remain_quantity: Option<i64>,
    /// 优惠券总数量
    #[serde(default)]
    pub coupon_total_quantity: Option<i64>,
    /// 优惠券开始时间 (秒级时间戳)
    #[serde(default)]
    pub coupon_start_time: Option<i64>,
    /// 优惠券结束时间 (秒级时间戳)
    #[serde(default)]
    pub coupon_end_time: Option<i64>,
    /// 店铺 ID
    #[serde(default)]
    pub mall_id: Option<i64>,
    /// 店铺名称
    #[serde(default)]
    pub mall_name: Option<String>,
    /// 店铺类型: 1-个人,2-企业,3-旗舰店,4-专卖店,5-专营店,6-普通店
    #[serde(default)]
    pub merchant_type: Option<i32>,
    /// 商品类目 ID
    #[serde(default)]
    pub cat_id: Option<i64>,
    /// 商品类目名称
    #[serde(default)]
    pub cat_name: Option<String>,
    /// 一级类目 ID
    #[serde(default, rename = "cat_id_1")]
    pub cat_id1: Option<i64>,
    /// 二级类目 ID
    #[serde(default, rename = "cat_id_2")]
    pub cat_id2: Option<i64>,
    /// 三级类目 ID
    #[serde(default, rename = "cat_id_3")]
    pub cat_id3: Option<i64>,
    /// 一级类目名称
    #[serde(default, rename = "cat_name_1")]
    pub cat_name1: Option<String>,
    /// 二级类目名称
    #[serde(default, rename = "cat_name_2")]
    pub cat_name2: Option<String>,
    /// 三级类目名称
    #[serde(default, rename = "cat_name_3")]
    pub cat_name3: Option<String>,
    /// 是否有优惠券
    #[serde(default)]
    pub has_coupon: Option<bool>,
    /// 是否品牌商品
    #[serde(default)]
    pub is_brand_goods: Option<bool>,
    /// 描述评分
    #[serde(default)]
    pub desc_txt: Option<String>,
    /// 物流评分
    #[serde(default)]
    pub lgst_txt: Option<String>,
    /// 服务评分
    #[serde(default)]
    pub serv_txt: Option<String>,
    /// 活动标签
    #[serde(default)]
    pub activity_tags: Option<Vec<i32>>,
}

/// 拼多多订单查询响应
///
/// query_orders 接口的响应
#[derive(Debug, Clone, Deserialize)]
pub struct PddOrderResponse {
    /// 订单查询结果
    #[serde(default, rename = "order_list_get_response")]
    pub response: Option<PddOrderListResult>,
}

/// 拼多多订单列表结果
#[derive(Debug, Clone, Deserialize)]
pub struct PddOrderListResult {
    /// 订单总数
    #[serde(default)]
    pub total_count: Option<i64>,
    /// 订单列表
    #[serde(default)]
    pub order_list: Option<Vec<PddOrderInfo>>,
    /// 请求 ID
    #[serde(default)]
    pub request_id: Option<String>,
}

/// 拼多多订单信息
#[derive(Debug, Clone, Deserialize)]
pub struct PddOrderInfo {
    /// 订单号
    #[serde(default)]
    pub order_sn: Option<String>,
    /// 商品 ID
    #[serde(default)]
    pub goods_id: Option<i64>,
    /// 商品名称
    #[serde(default)]
    pub goods_name: Option<String>,
    /// 商品主图
    #[serde(default)]
    pub goods_thumbnail_url: Option<String>,
    /// 商品数量
    #[serde(default)]
    pub goods_quantity: Option<i32>,
    /// 商品价格 (单位: 分)
    #[serde(default)]
    pub goods_price: Option<i64>,
    /// 订单金额 (单位: 分)
    #[serde(default)]
    pub order_amount: Option<i64>,
    /// 佣金金额 (单位: 分)
    #[serde(default)]
    pub promotion_amount: Option<i64>,
    /// 佣金比例 (千分比)
    #[serde(default)]
    pub promotion_rate: Option<i64>,
    /// 订单状态: -1-未支付,0-已支付,1-已成团,2-确认收货,3-审核成功,4-审核失败,5-已经结算,8-非多多进宝商品
    #[serde(default)]
    pub order_status: Option<i32>,
    /// 订单状态描述
    #[serde(default)]
    pub order_status_desc: Option<String>,
    /// 订单创建时间 (秒级时间戳)
    #[serde(default)]
    pub order_create_time: Option<i64>,
    /// 订单支付时间 (秒级时间戳)
    #[serde(default)]
    pub order_pay_time: Option<i64>,
    /// 订单成团时间 (秒级时间戳)
    #[serde(default)]
    pub order_group_success_time: Option<i64>,
    /// 订单确认收货时间 (秒级时间戳)
    #[serde(default)]
    pub order_receive_time: Option<i64>,
    /// 订单结算时间 (秒级时间戳)
    #[serde(default)]
    pub order_settle_time: Option<i64>,
    /// 订单更新时间 (秒级时间戳)
    #[serde(default)]
    pub order_modify_at: Option<i64>,
    /// 自定义参数
    #[serde(default)]
    pub custom_parameters: Option<String>,
    /// 推广位 ID
    #[serde(default)]
    pub p_id: Option<String>,
    /// 是否直推: 1-直推,0-非直推
    #[serde(default)]
    pub type_field: Option<i32>,
    /// 订单类型: 0-普通订单,1-礼金订单
    #[serde(default)]
    pub order_type: Option<i32>,
    /// 店铺 ID
    #[serde(default)]
    pub mall_id: Option<i64>,
    /// 店铺名称
    #[serde(default)]
    pub mall_name: Option<String>,
    /// 类目 ID
    #[serde(default)]
    pub cat_ids: Option<Vec<i64>>,
}

/// 拼多多授权备案响应
///
/// authorize 接口的响应
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeResponse {
    /// 授权备案结果
    #[serde(default, rename = "rp_promotion_url_generate_response")]
    pub response: Option<PddAuthorizeResult>,
}

/// 拼多多授权备案结果
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeResult {
    /// URL 列表
    #[serde(default)]
    pub url_list: Option<Vec<PddAuthorizeUrl>>,
    /// 请求 ID
    #[serde(default)]
    pub request_id: Option<String>,
}

/// 拼多多授权备案 URL
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeUrl {
    /// 移动版授权备案地址
    #[serde(default)]
    pub mobile_url: Option<String>,
    /// 电脑版授权备案地址
    #[serde(default)]
    pub url: Option<String>,
}

/// 拼多多授权备案查询响应
///
/// authorize_query 接口的响应
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeQueryResponse {
    /// 授权查询结果
    #[serde(default, rename = "authority_query_response")]
    pub response: Option<PddAuthorizeQueryResult>,
}

/// 拼多多授权备案查询结果
#[derive(Debug, Clone, Deserialize)]
pub struct PddAuthorizeQueryResult {
    /// 绑定状态: 1 表示授权备案成功,其他值表示失败
    #[serde(default)]
    pub bind: Option<i32>,
    /// 请求 ID
    #[serde(default)]
    pub request_id: Option<String>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_pdd_convert_response_deserialize() {
        let json = r#"{
            "goods_zs_unit_generate_response": {
                "multi_group_mobile_short_url": "https://p.pinduoduo.com/2sB0eGpK",
                "mobile_url": "https://mobile.yangkeduo.com/duo_coupon_landing.html",
                "short_url": "https://p.pinduoduo.com/bOL0pBPH",
                "request_id": "16942627387113959"
            }
        }"#;

        let response: PddConvertResponse = serde_json::from_str(json).unwrap();
        assert!(response.response.is_some());
        let result = response.response.unwrap();
        assert_eq!(
            result.multi_group_mobile_short_url,
            Some("https://p.pinduoduo.com/2sB0eGpK".to_string())
        );
        assert_eq!(
            result.short_url,
            Some("https://p.pinduoduo.com/bOL0pBPH".to_string())
        );
    }

    #[test]
    fn test_pdd_goods_detail_simple_response_deserialize() {
        let json = r#"{
            "goods_basic_detail_response": {
                "goods_list": [{
                    "goods_name": "测试商品",
                    "goods_pic": "https://img.pddpic.com/test.jpeg",
                    "min_normal_price": 1900,
                    "goods_id": 453581732819,
                    "min_group_price": 990
                }],
                "request_id": "16942480364163726"
            }
        }"#;

        let response: PddGoodsDetailSimpleResponse = serde_json::from_str(json).unwrap();
        assert!(response.response.is_some());
        let result = response.response.unwrap();
        assert!(result.goods_list.is_some());
        let goods = result.goods_list.unwrap();
        assert_eq!(goods.len(), 1);
        assert_eq!(goods[0].goods_name, Some("测试商品".to_string()));
        assert_eq!(goods[0].goods_id, Some(453581732819));
    }

    #[test]
    fn test_pdd_order_response_deserialize() {
        let json = r#"{
            "order_list_get_response": {
                "total_count": 1,
                "order_list": [{
                    "order_sn": "123456789",
                    "goods_id": 453581732819,
                    "goods_name": "测试商品",
                    "order_status": 2,
                    "order_amount": 9900,
                    "promotion_amount": 990
                }],
                "request_id": "16942626445817516"
            }
        }"#;

        let response: PddOrderResponse = serde_json::from_str(json).unwrap();
        assert!(response.response.is_some());
        let result = response.response.unwrap();
        assert_eq!(result.total_count, Some(1));
        assert!(result.order_list.is_some());
        let orders = result.order_list.unwrap();
        assert_eq!(orders.len(), 1);
        assert_eq!(orders[0].order_sn, Some("123456789".to_string()));
        assert_eq!(orders[0].order_status, Some(2));
    }

    #[test]
    fn test_pdd_authorize_response_deserialize() {
        let json = r#"{
            "rp_promotion_url_generate_response": {
                "url_list": [{
                    "mobile_url": "https://mobile.yangkeduo.com/duo_coupon_landing.html_",
                    "url": "https://mobile.yangkeduo.com/duo_coupon_landing.html"
                }],
                "request_id": "16942480613190789"
            }
        }"#;

        let response: PddAuthorizeResponse = serde_json::from_str(json).unwrap();
        assert!(response.response.is_some());
        let result = response.response.unwrap();
        assert!(result.url_list.is_some());
        let urls = result.url_list.unwrap();
        assert_eq!(urls.len(), 1);
        assert!(urls[0].mobile_url.is_some());
    }

    #[test]
    fn test_pdd_authorize_query_response_deserialize() {
        let json = r#"{
            "authority_query_response": {
                "bind": 1,
                "request_id": "16942467231374196"
            }
        }"#;

        let response: PddAuthorizeQueryResponse = serde_json::from_str(json).unwrap();
        assert!(response.response.is_some());
        let result = response.response.unwrap();
        assert_eq!(result.bind, Some(1));
    }

    #[test]
    fn test_response_with_missing_fields() {
        let json = r#"{"order_list_get_response": {"total_count": 0}}"#;

        let response: PddOrderResponse = serde_json::from_str(json).unwrap();
        assert!(response.response.is_some());
        let result = response.response.unwrap();
        assert_eq!(result.total_count, Some(0));
        assert!(result.order_list.is_none());
    }
}