Skip to main content

bpi_rs/manga/
comic.rs

1//! 购买漫画章节
2//!
3//! [查看 API 文档](https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/manga/Comic.md)
4
5use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
6use serde::Serialize;
7
8// ================= 数据结构 =================
9
10/// 购买漫画章节请求参数
11#[derive(Debug, Clone, Serialize)]
12pub struct BuyEpisodeRequest {
13    /// 章节id
14    #[serde(rename = "epId")]
15    pub ep_id: i32,
16
17    /// 购买方式
18    /// 2:漫读券
19    /// 4:新人等免
20    /// 5:通用券
21    #[serde(rename = "buyMethod")]
22    pub buy_method: i32,
23
24    /// 漫读券id
25    #[serde(rename = "couponId")]
26    pub coupon_id: i32,
27
28    /// 漫画id,buyMethod=4时必填
29    #[serde(rename = "comicId", skip_serializing_if = "Option::is_none")]
30    pub comic_id: Option<i32>,
31
32    /// 自动支付状态,buyMethod=2,5时必填
33    #[serde(rename = "autoPayGoldStatus", skip_serializing_if = "Option::is_none")]
34    pub auto_pay_gold_status: Option<i32>,
35
36    /// 是否预售,buyMethod=2,5时必填
37    #[serde(rename = "isPresale", skip_serializing_if = "Option::is_none")]
38    pub is_presale: Option<i32>,
39
40    /// 支付金额,buyMethod=5时必填
41    #[serde(rename = "payAmount", skip_serializing_if = "Option::is_none")]
42    pub pay_amount: Option<i32>,
43}
44
45// ================= 实现 =================
46
47impl BpiClient {
48    /// 购买漫画章节
49    ///
50    /// [网页入口](https://manga.bilibili.com/twirp/comic.v1.Comic/BuyEpisode)
51    pub async fn manga_buy_episode(
52        &self,
53        request: BuyEpisodeRequest
54    ) -> Result<BpiResponse<serde_json::Value>, BpiError> {
55        let result = self
56            .post("https://manga.bilibili.com/twirp/comic.v1.Comic/BuyEpisode?platform=web")
57            .json(&request)
58            .send_bpi("购买漫画章节").await?;
59
60        Ok(result)
61    }
62
63    /// 使用漫读券购买漫画章节
64    ///
65    /// [网页入口](https://manga.bilibili.com/twirp/comic.v1.Comic/BuyEpisode)
66    pub async fn manga_buy_episode_with_coupon(
67        &self,
68        ep_id: i32,
69        coupon_id: i32
70    ) -> Result<BpiResponse<serde_json::Value>, BpiError> {
71        let request = BuyEpisodeRequest {
72            ep_id: ep_id,
73            buy_method: 2,
74            coupon_id: coupon_id,
75            comic_id: None,
76            auto_pay_gold_status: Some(2),
77            is_presale: Some(0),
78            pay_amount: None,
79        };
80
81        self.manga_buy_episode(request).await
82    }
83
84    /// 使用新人等免购买漫画章节
85    ///
86    /// [网页入口](https://manga.bilibili.com/twirp/comic.v1.Comic/BuyEpisode)
87    pub async fn manga_buy_episode_with_free(
88        &self,
89        comic_id: i32,
90        ep_id: i32
91    ) -> Result<BpiResponse<serde_json::Value>, BpiError> {
92        let request = BuyEpisodeRequest {
93            ep_id: ep_id,
94            buy_method: 4,
95            coupon_id: 0,
96            comic_id: Some(comic_id),
97            auto_pay_gold_status: None,
98            is_presale: None,
99            pay_amount: None,
100        };
101
102        self.manga_buy_episode(request).await
103    }
104
105    /// 使用通用券购买漫画章节
106    ///
107    /// [网页入口](https://manga.bilibili.com/twirp/comic.v1.Comic/BuyEpisode)
108    pub async fn manga_buy_episode_with_general_coupon(
109        &self,
110        ep_id: i32,
111        pay_amount: i32
112    ) -> Result<BpiResponse<serde_json::Value>, BpiError> {
113        let request = BuyEpisodeRequest {
114            ep_id: ep_id,
115            buy_method: 5,
116            coupon_id: 0,
117            comic_id: None,
118            auto_pay_gold_status: Some(2),
119            is_presale: Some(0),
120            pay_amount: Some(pay_amount),
121        };
122
123        self.manga_buy_episode(request).await
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[tokio::test]
132    async fn test_manga_buy_episode_with_coupon() -> Result<(), Box<BpiError>> {
133        let bpi = BpiClient::new();
134
135        let coupon_id = 12553634;
136        let ep_id = 484360;
137
138        let _result = bpi.manga_buy_episode_with_coupon(ep_id, coupon_id).await?;
139
140        Ok(())
141    }
142}