ztk_rust_sdk/pdd/
request.rs

1//! 拼多多平台请求参数结构体
2//!
3//! 定义拼多多平台 API 的请求参数结构体
4
5use serde::Serialize;
6
7/// 拼多多转链请求
8///
9/// 将商品 ID 或推广短链转换为推广链接
10///
11/// # Example
12///
13/// ```rust,ignore
14/// let request = PddConvertRequest::new("pdd_app_key", "pdd_app_secret", "pid", "453581732819")
15///     .custom_parameters(r#"{"uid":"user123"}"#);
16/// ```
17#[derive(Debug, Clone, Serialize)]
18pub struct PddConvertRequest {
19    /// 拼多多开放平台应用的 appkey
20    pub pdd_app_key: String,
21    /// 拼多多开放平台应用的 appsecret
22    pub pdd_app_secret: String,
23    /// 拼多多平台的推广位
24    pub pid: String,
25    /// 商品内容,支持纯数字 ID 或拼多多推广短链
26    pub content: String,
27    /// 自定义参数,为链接打上自定义标签 (可选)
28    /// 格式为 JSON: {"uid":"15611448080","sid":""}
29    /// 用于返利场景,需要 URL 编码
30    #[serde(skip_serializing_if = "Option::is_none")]
31    pub custom_parameters: Option<String>,
32}
33
34impl PddConvertRequest {
35    /// 创建新的拼多多转链请求
36    ///
37    /// # Arguments
38    ///
39    /// * `pdd_app_key` - 拼多多开放平台应用的 appkey
40    /// * `pdd_app_secret` - 拼多多开放平台应用的 appsecret
41    /// * `pid` - 拼多多平台的推广位
42    /// * `content` - 商品 ID 或推广短链
43    pub fn new(
44        pdd_app_key: impl Into<String>,
45        pdd_app_secret: impl Into<String>,
46        pid: impl Into<String>,
47        content: impl Into<String>,
48    ) -> Self {
49        Self {
50            pdd_app_key: pdd_app_key.into(),
51            pdd_app_secret: pdd_app_secret.into(),
52            pid: pid.into(),
53            content: content.into(),
54            custom_parameters: None,
55        }
56    }
57
58    /// 设置自定义参数 (用于返利场景)
59    pub fn custom_parameters(mut self, custom_parameters: impl Into<String>) -> Self {
60        self.custom_parameters = Some(custom_parameters.into());
61        self
62    }
63}
64
65/// 拼多多商品详情请求 (简版)
66///
67/// 获取拼多多商品的基本详情信息
68///
69/// # Example
70///
71/// ```rust,ignore
72/// let request = PddGoodsDetailSimpleRequest::new("pdd_app_key", "pdd_app_secret", "pid", "453581732819");
73/// ```
74#[derive(Debug, Clone, Serialize)]
75pub struct PddGoodsDetailSimpleRequest {
76    /// 拼多多开放平台应用的 appkey
77    pub pdd_app_key: String,
78    /// 拼多多开放平台应用的 appsecret
79    pub pdd_app_secret: String,
80    /// 拼多多平台的推广位
81    pub pid: String,
82    /// 商品 ID (纯数字)
83    pub content: String,
84}
85
86impl PddGoodsDetailSimpleRequest {
87    /// 创建新的拼多多商品详情请求 (简版)
88    ///
89    /// # Arguments
90    ///
91    /// * `pdd_app_key` - 拼多多开放平台应用的 appkey
92    /// * `pdd_app_secret` - 拼多多开放平台应用的 appsecret
93    /// * `pid` - 拼多多平台的推广位
94    /// * `content` - 商品 ID
95    pub fn new(
96        pdd_app_key: impl Into<String>,
97        pdd_app_secret: impl Into<String>,
98        pid: impl Into<String>,
99        content: impl Into<String>,
100    ) -> Self {
101        Self {
102            pdd_app_key: pdd_app_key.into(),
103            pdd_app_secret: pdd_app_secret.into(),
104            pid: pid.into(),
105            content: content.into(),
106        }
107    }
108}
109
110/// 拼多多商品详情请求 (详版)
111///
112/// 获取拼多多商品的详细信息,支持多种筛选条件
113///
114/// # Example
115///
116/// ```rust,ignore
117/// let request = PddGoodsDetailFullRequest::new("pdd_app_key", "pdd_app_secret", "pid", "453581732819")
118///     .custom_parameters(r#"{"uid":"user123"}"#)
119///     .sort_type(2);
120/// ```
121#[derive(Debug, Clone, Serialize)]
122pub struct PddGoodsDetailFullRequest {
123    /// 拼多多开放平台应用的 appkey
124    pub pdd_app_key: String,
125    /// 拼多多开放平台应用的 appsecret
126    pub pdd_app_secret: String,
127    /// 拼多多平台的推广位
128    pub pid: String,
129    /// 商品关键词,支持 goods_id、拼多多商品链接、推广长链和推广短链
130    pub keyword: String,
131    /// 自定义参数 (可选,用于返利场景)
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub custom_parameters: Option<String>,
134    /// 商品类目 ID (可选)
135    #[serde(skip_serializing_if = "Option::is_none")]
136    pub cat_id: Option<String>,
137    /// 活动商品标记数组 (可选)
138    /// 例: [4,7],4-秒杀,7-百亿补贴,10851-千万补贴
139    #[serde(skip_serializing_if = "Option::is_none")]
140    pub activity_tags: Option<String>,
141    /// 屏蔽商品类目包 (可选)
142    /// 1-拼多多小程序屏蔽的类目&关键词,2-虚拟类目,3-医疗器械等
143    #[serde(skip_serializing_if = "Option::is_none")]
144    pub block_cat_packages: Option<String>,
145    /// 自定义屏蔽类目 ID (可选,最多 20 个)
146    #[serde(skip_serializing_if = "Option::is_none")]
147    pub block_cats: Option<String>,
148    /// 是否为品牌商品 (可选)
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub is_brand_goods: Option<bool>,
151    /// 店铺类型 (可选)
152    /// 1-个人,2-企业,3-旗舰店,4-专卖店,5-专营店,6-普通店
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub merchant_type: Option<u32>,
155    /// 排序方式 (可选)
156    /// 0-综合排序,1-按佣金比率升序,2-按佣金比例降序,3-按价格升序,4-按价格降序等
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub sort_type: Option<u32>,
159    /// 是否使用个性化推荐 (可选,默认 true)
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub use_customized: Option<bool>,
162    /// 是否只返回有优惠券的商品 (可选)
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub with_coupon: Option<bool>,
165}
166
167impl PddGoodsDetailFullRequest {
168    /// 创建新的拼多多商品详情请求 (详版)
169    pub fn new(
170        pdd_app_key: impl Into<String>,
171        pdd_app_secret: impl Into<String>,
172        pid: impl Into<String>,
173        keyword: impl Into<String>,
174    ) -> Self {
175        Self {
176            pdd_app_key: pdd_app_key.into(),
177            pdd_app_secret: pdd_app_secret.into(),
178            pid: pid.into(),
179            keyword: keyword.into(),
180            custom_parameters: None,
181            cat_id: None,
182            activity_tags: None,
183            block_cat_packages: None,
184            block_cats: None,
185            is_brand_goods: None,
186            merchant_type: None,
187            sort_type: None,
188            use_customized: None,
189            with_coupon: None,
190        }
191    }
192
193    /// 设置自定义参数
194    pub fn custom_parameters(mut self, custom_parameters: impl Into<String>) -> Self {
195        self.custom_parameters = Some(custom_parameters.into());
196        self
197    }
198
199    /// 设置商品类目 ID
200    pub fn cat_id(mut self, cat_id: impl Into<String>) -> Self {
201        self.cat_id = Some(cat_id.into());
202        self
203    }
204
205    /// 设置活动商品标记
206    pub fn activity_tags(mut self, activity_tags: impl Into<String>) -> Self {
207        self.activity_tags = Some(activity_tags.into());
208        self
209    }
210
211    /// 设置屏蔽商品类目包
212    pub fn block_cat_packages(mut self, block_cat_packages: impl Into<String>) -> Self {
213        self.block_cat_packages = Some(block_cat_packages.into());
214        self
215    }
216
217    /// 设置自定义屏蔽类目
218    pub fn block_cats(mut self, block_cats: impl Into<String>) -> Self {
219        self.block_cats = Some(block_cats.into());
220        self
221    }
222
223    /// 设置是否为品牌商品
224    pub fn is_brand_goods(mut self, is_brand_goods: bool) -> Self {
225        self.is_brand_goods = Some(is_brand_goods);
226        self
227    }
228
229    /// 设置店铺类型
230    pub fn merchant_type(mut self, merchant_type: u32) -> Self {
231        self.merchant_type = Some(merchant_type);
232        self
233    }
234
235    /// 设置排序方式
236    pub fn sort_type(mut self, sort_type: u32) -> Self {
237        self.sort_type = Some(sort_type);
238        self
239    }
240
241    /// 设置是否使用个性化推荐
242    pub fn use_customized(mut self, use_customized: bool) -> Self {
243        self.use_customized = Some(use_customized);
244        self
245    }
246
247    /// 设置是否只返回有优惠券的商品
248    pub fn with_coupon(mut self, with_coupon: bool) -> Self {
249        self.with_coupon = Some(with_coupon);
250        self
251    }
252}
253
254/// 拼多多订单查询请求
255///
256/// 查询拼多多推广订单
257///
258/// # Example
259///
260/// ```rust,ignore
261/// let request = PddOrderQueryRequest::new("pdd_app_key", "pdd_app_secret", 1699200000, 1699286400)
262///     .page(1)
263///     .page_size(50);
264/// ```
265#[derive(Debug, Clone, Serialize)]
266pub struct PddOrderQueryRequest {
267    /// 拼多多开放平台应用的 appkey
268    pub pdd_app_key: String,
269    /// 拼多多开放平台应用的 appsecret
270    pub pdd_app_secret: String,
271    /// 查询开始时间 (10 位秒级时间戳)
272    pub start_update_time: i64,
273    /// 查询结束时间 (10 位秒级时间戳,与开始时间相差不超过 24 小时)
274    pub end_update_time: i64,
275    /// 订单类型 (可选): 1-推广订单,2-直播间订单
276    #[serde(skip_serializing_if = "Option::is_none")]
277    pub query_order_type: Option<u32>,
278    /// 页码 (可选,从 1 到 10000,默认 1)
279    #[serde(skip_serializing_if = "Option::is_none")]
280    pub page: Option<u32>,
281    /// 每页数量 (可选,默认 100,范围 10-100)
282    #[serde(skip_serializing_if = "Option::is_none")]
283    pub page_size: Option<u32>,
284    /// 是否为礼金订单 (可选)
285    #[serde(skip_serializing_if = "Option::is_none")]
286    pub cash_gift_order: Option<bool>,
287}
288
289impl PddOrderQueryRequest {
290    /// 创建新的拼多多订单查询请求
291    ///
292    /// # Arguments
293    ///
294    /// * `pdd_app_key` - 拼多多开放平台应用的 appkey
295    /// * `pdd_app_secret` - 拼多多开放平台应用的 appsecret
296    /// * `start_update_time` - 查询开始时间 (10 位秒级时间戳)
297    /// * `end_update_time` - 查询结束时间 (10 位秒级时间戳)
298    pub fn new(
299        pdd_app_key: impl Into<String>,
300        pdd_app_secret: impl Into<String>,
301        start_update_time: i64,
302        end_update_time: i64,
303    ) -> Self {
304        Self {
305            pdd_app_key: pdd_app_key.into(),
306            pdd_app_secret: pdd_app_secret.into(),
307            start_update_time,
308            end_update_time,
309            query_order_type: None,
310            page: None,
311            page_size: None,
312            cash_gift_order: None,
313        }
314    }
315
316    /// 设置订单类型
317    pub fn query_order_type(mut self, query_order_type: u32) -> Self {
318        self.query_order_type = Some(query_order_type);
319        self
320    }
321
322    /// 设置页码
323    pub fn page(mut self, page: u32) -> Self {
324        self.page = Some(page);
325        self
326    }
327
328    /// 设置每页数量
329    pub fn page_size(mut self, page_size: u32) -> Self {
330        self.page_size = Some(page_size);
331        self
332    }
333
334    /// 设置是否为礼金订单
335    pub fn cash_gift_order(mut self, cash_gift_order: bool) -> Self {
336        self.cash_gift_order = Some(cash_gift_order);
337        self
338    }
339}
340
341/// 拼多多授权备案请求
342///
343/// 获取授权备案 URL,用于在服务器上进行 PID 授权备案
344///
345/// # Example
346///
347/// ```rust,ignore
348/// let request = PddAuthorizeRequest::new("pdd_app_key", "pdd_app_secret", "pid");
349/// ```
350#[derive(Debug, Clone, Serialize)]
351pub struct PddAuthorizeRequest {
352    /// 拼多多开放平台应用的 appkey
353    pub pdd_app_key: String,
354    /// 拼多多开放平台应用的 appsecret
355    pub pdd_app_secret: String,
356    /// 拼多多平台的推广位
357    pub pid: String,
358    /// 自定义参数 (可选,用于返利场景)
359    #[serde(skip_serializing_if = "Option::is_none")]
360    pub custom_parameters: Option<String>,
361    /// 是否生成 QQ 小程序 (可选,默认 false)
362    #[serde(skip_serializing_if = "Option::is_none")]
363    pub generate_qq_app: Option<bool>,
364    /// 是否生成微信小程序推广信息 (可选,默认 false)
365    #[serde(skip_serializing_if = "Option::is_none")]
366    pub generate_we_app: Option<bool>,
367}
368
369impl PddAuthorizeRequest {
370    /// 创建新的拼多多授权备案请求
371    ///
372    /// # Arguments
373    ///
374    /// * `pdd_app_key` - 拼多多开放平台应用的 appkey
375    /// * `pdd_app_secret` - 拼多多开放平台应用的 appsecret
376    /// * `pid` - 拼多多平台的推广位
377    pub fn new(
378        pdd_app_key: impl Into<String>,
379        pdd_app_secret: impl Into<String>,
380        pid: impl Into<String>,
381    ) -> Self {
382        Self {
383            pdd_app_key: pdd_app_key.into(),
384            pdd_app_secret: pdd_app_secret.into(),
385            pid: pid.into(),
386            custom_parameters: None,
387            generate_qq_app: None,
388            generate_we_app: None,
389        }
390    }
391
392    /// 设置自定义参数
393    pub fn custom_parameters(mut self, custom_parameters: impl Into<String>) -> Self {
394        self.custom_parameters = Some(custom_parameters.into());
395        self
396    }
397
398    /// 设置是否生成 QQ 小程序
399    pub fn generate_qq_app(mut self, generate_qq_app: bool) -> Self {
400        self.generate_qq_app = Some(generate_qq_app);
401        self
402    }
403
404    /// 设置是否生成微信小程序推广信息
405    pub fn generate_we_app(mut self, generate_we_app: bool) -> Self {
406        self.generate_we_app = Some(generate_we_app);
407        self
408    }
409}
410
411/// 拼多多授权备案查询请求
412///
413/// 查询 PID 授权备案状态
414///
415/// # Example
416///
417/// ```rust,ignore
418/// let request = PddAuthorizeQueryRequest::new("pdd_app_key", "pdd_app_secret", "pid");
419/// ```
420#[derive(Debug, Clone, Serialize)]
421pub struct PddAuthorizeQueryRequest {
422    /// 拼多多开放平台应用的 appkey
423    pub pdd_app_key: String,
424    /// 拼多多开放平台应用的 appsecret
425    pub pdd_app_secret: String,
426    /// 拼多多平台的推广位
427    pub pid: String,
428    /// 自定义参数 (可选)
429    #[serde(skip_serializing_if = "Option::is_none")]
430    pub custom_parameters: Option<String>,
431}
432
433impl PddAuthorizeQueryRequest {
434    /// 创建新的拼多多授权备案查询请求
435    pub fn new(
436        pdd_app_key: impl Into<String>,
437        pdd_app_secret: impl Into<String>,
438        pid: impl Into<String>,
439    ) -> Self {
440        Self {
441            pdd_app_key: pdd_app_key.into(),
442            pdd_app_secret: pdd_app_secret.into(),
443            pid: pid.into(),
444            custom_parameters: None,
445        }
446    }
447
448    /// 设置自定义参数
449    pub fn custom_parameters(mut self, custom_parameters: impl Into<String>) -> Self {
450        self.custom_parameters = Some(custom_parameters.into());
451        self
452    }
453}
454
455#[cfg(test)]
456mod tests {
457    use super::*;
458
459    #[test]
460    fn test_pdd_convert_request_serialize() {
461        let request = PddConvertRequest::new("app_key", "app_secret", "pid123", "453581732819");
462        let json = serde_json::to_value(&request).unwrap();
463
464        assert_eq!(json["pdd_app_key"], "app_key");
465        assert_eq!(json["pdd_app_secret"], "app_secret");
466        assert_eq!(json["pid"], "pid123");
467        assert_eq!(json["content"], "453581732819");
468        assert!(json.get("custom_parameters").is_none());
469    }
470
471    #[test]
472    fn test_pdd_convert_request_with_custom_parameters() {
473        let request = PddConvertRequest::new("app_key", "app_secret", "pid123", "453581732819")
474            .custom_parameters(r#"{"uid":"user123"}"#);
475
476        let json = serde_json::to_value(&request).unwrap();
477        assert_eq!(json["custom_parameters"], r#"{"uid":"user123"}"#);
478    }
479
480    #[test]
481    fn test_pdd_goods_detail_simple_request_serialize() {
482        let request =
483            PddGoodsDetailSimpleRequest::new("app_key", "app_secret", "pid123", "453581732819");
484        let json = serde_json::to_value(&request).unwrap();
485
486        assert_eq!(json["pdd_app_key"], "app_key");
487        assert_eq!(json["content"], "453581732819");
488    }
489
490    #[test]
491    fn test_pdd_goods_detail_full_request_serialize() {
492        let request =
493            PddGoodsDetailFullRequest::new("app_key", "app_secret", "pid123", "453581732819")
494                .sort_type(2)
495                .merchant_type(3)
496                .with_coupon(true);
497
498        let json = serde_json::to_value(&request).unwrap();
499
500        assert_eq!(json["keyword"], "453581732819");
501        assert_eq!(json["sort_type"], 2);
502        assert_eq!(json["merchant_type"], 3);
503        assert_eq!(json["with_coupon"], true);
504    }
505
506    #[test]
507    fn test_pdd_order_query_request_serialize() {
508        let request = PddOrderQueryRequest::new("app_key", "app_secret", 1699200000, 1699286400)
509            .page(1)
510            .page_size(50);
511
512        let json = serde_json::to_value(&request).unwrap();
513
514        assert_eq!(json["start_update_time"], 1699200000);
515        assert_eq!(json["end_update_time"], 1699286400);
516        assert_eq!(json["page"], 1);
517        assert_eq!(json["page_size"], 50);
518    }
519
520    #[test]
521    fn test_pdd_authorize_request_serialize() {
522        let request =
523            PddAuthorizeRequest::new("app_key", "app_secret", "pid123").generate_we_app(true);
524
525        let json = serde_json::to_value(&request).unwrap();
526
527        assert_eq!(json["pdd_app_key"], "app_key");
528        assert_eq!(json["pid"], "pid123");
529        assert_eq!(json["generate_we_app"], true);
530    }
531
532    #[test]
533    fn test_optional_fields_not_serialized() {
534        let request = PddConvertRequest::new("app_key", "app_secret", "pid", "content");
535        let json_str = serde_json::to_string(&request).unwrap();
536
537        assert!(!json_str.contains("custom_parameters"));
538    }
539}