1use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
6use serde::Serialize;
7
8#[derive(Debug, Clone, Serialize)]
12pub struct BuyEpisodeRequest {
13 #[serde(rename = "epId")]
15 pub ep_id: i32,
16
17 #[serde(rename = "buyMethod")]
22 pub buy_method: i32,
23
24 #[serde(rename = "couponId")]
26 pub coupon_id: i32,
27
28 #[serde(rename = "comicId", skip_serializing_if = "Option::is_none")]
30 pub comic_id: Option<i32>,
31
32 #[serde(rename = "autoPayGoldStatus", skip_serializing_if = "Option::is_none")]
34 pub auto_pay_gold_status: Option<i32>,
35
36 #[serde(rename = "isPresale", skip_serializing_if = "Option::is_none")]
38 pub is_presale: Option<i32>,
39
40 #[serde(rename = "payAmount", skip_serializing_if = "Option::is_none")]
42 pub pay_amount: Option<i32>,
43}
44
45impl BpiClient {
48 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 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 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 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}