1use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
6use serde::{ Deserialize, Serialize };
7
8#[derive(Debug, Serialize, Clone, Deserialize)]
10pub struct UserCoupon {
11 #[serde(rename = "ID")]
13 pub id: i32,
14 pub remain_amount: i32,
16 pub total_amount: u32,
18}
19
20#[derive(Debug, Serialize, Clone, Deserialize)]
22pub struct CouponsData {
23 pub total_remain_amount: i32,
25 pub user_coupons: Vec<UserCoupon>,
27 pub coupon_info: CouponInfo,
29}
30
31#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct CouponInfo {
33 pub remain_coupon: i64,
35 pub remain_silver: i64,
37 pub remain_shop_coupon: i64,
39}
40
41#[derive(Debug, Clone, Serialize)]
43pub struct GetCouponsRequest {
44 #[serde(rename = "pageNum")]
46 pub page_num: i32,
47
48 #[serde(rename = "pageSize")]
50 pub page_size: i32,
51
52 #[serde(rename = "notExpired", skip_serializing_if = "Option::is_none")]
54 pub not_expired: Option<bool>,
55
56 #[serde(rename = "tabType", skip_serializing_if = "Option::is_none")]
58 pub tab_type: Option<i32>,
59
60 #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
62 pub r#type: Option<i32>,
63}
64
65impl BpiClient {
68 pub async fn manga_coupons(
80 &self,
81 page_num: i32,
82 page_size: i32
83 ) -> Result<BpiResponse<CouponsData>, BpiError> {
84 let params = GetCouponsRequest {
85 page_num: page_num,
86 page_size: page_size,
87 not_expired: Some(true),
88 tab_type: Some(1),
89 r#type: Some(0),
90 };
91
92 self
93 .post("https://manga.bilibili.com/twirp/user.v1.User/GetCoupons")
94 .json(¶ms)
95 .send_bpi("获取漫读券列表").await
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[tokio::test]
104 async fn test_get_manga_coupons() -> Result<(), Box<BpiError>> {
105 let bpi = BpiClient::new();
106
107 let result = bpi.manga_coupons(1, 20).await?;
108
109 tracing::info!("{:#?}", result.data.unwrap());
110
111 Ok(())
112 }
113}