bpi_rs/user/
status_number.rs1use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
5use serde::{ Deserialize, Serialize };
6
7#[derive(Debug, Clone, Deserialize, Serialize)]
11pub struct RelationStatResponseData {
12 pub mid: u64,
14 pub following: u64,
16 pub whisper: u64,
18 pub black: u64,
20 pub follower: u64,
22}
23
24#[derive(Debug, Clone, Deserialize, Serialize)]
26pub struct UpstatArchive {
27 pub view: u64,
29}
30
31#[derive(Debug, Clone, Deserialize, Serialize)]
33pub struct UpstatArticle {
34 pub view: u64,
36}
37
38#[derive(Debug, Clone, Deserialize, Serialize)]
40pub struct UpstatResponseData {
41 pub archive: UpstatArchive,
43 pub article: UpstatArticle,
45 pub likes: u64,
47}
48
49#[derive(Debug, Clone, Deserialize, Serialize)]
51pub struct NavnumChannel {
52 pub master: u64,
54 pub guest: u64,
56}
57
58#[derive(Debug, Clone, Deserialize, Serialize)]
60pub struct NavnumFavourite {
61 pub master: u64,
63 pub guest: u64,
65}
66
67#[derive(Debug, Clone, Deserialize, Serialize)]
69pub struct NavnumResponseData {
70 pub video: u64,
72 pub bangumi: u64,
74 pub cinema: u64,
76 pub channel: NavnumChannel,
78 pub favourite: NavnumFavourite,
80 pub tag: u64,
82 pub article: u64,
84 pub playlist: u64,
85 pub album: u64,
87 pub audio: u64,
89 pub pugv: u64,
91 pub opus: u64,
93 #[serde(rename = "season_num")]
95 pub season_num: u64,
96}
97
98#[derive(Debug, Clone, Deserialize, Serialize)]
100pub struct AlbumCountResponseData {
101 pub all_count: u64,
103 pub draw_count: u64,
105 pub photo_count: u64,
107 pub daily_count: u64,
109}
110
111impl BpiClient {
114 pub async fn user_relation_stat(
124 &self,
125 vmid: u64
126 ) -> Result<BpiResponse<RelationStatResponseData>, BpiError> {
127 self
128 .get("https://api.bilibili.com/x/relation/stat")
129 .query(&[("vmid", &vmid.to_string())])
130 .send_bpi("获取用户关系状态数").await
131 }
132
133 pub async fn user_up_stat(
143 &self,
144 mid: u64
145 ) -> Result<BpiResponse<UpstatResponseData>, BpiError> {
146 self
147 .get("https://api.bilibili.com/x/space/upstat")
148 .query(&[("mid", &mid.to_string())])
149 .send_bpi("获取 UP 主状态数").await
150 }
151
152 pub async fn user_navnum(&self, mid: u64) -> Result<BpiResponse<NavnumResponseData>, BpiError> {
162 self
163 .get("https://api.bilibili.com/x/space/navnum")
164 .query(&[("mid", &mid.to_string())])
165 .send_bpi("获取用户导航栏状态数").await
166 }
167
168 pub async fn user_album_count(
178 &self,
179 uid: u64
180 ) -> Result<BpiResponse<AlbumCountResponseData>, BpiError> {
181 self
182 .get("https://api.vc.bilibili.com/link_draw/v1/doc/upload_count")
183 .query(&[("uid", &uid.to_string())])
184 .send_bpi("获取相簿投稿数").await
185 }
186}
187
188#[cfg(test)]
191mod tests {
192 use super::*;
193 use tracing::info;
194
195 const TEST_MID: u64 = 332704117;
198 const TEST_UP_MID: u64 = 456664753;
199 const TEST_NAV_MID: u64 = 645769214;
200
201 #[tokio::test]
202 async fn test_get_relation_stat() -> Result<(), BpiError> {
203 let bpi = BpiClient::new();
204 let resp = bpi.user_relation_stat(TEST_MID).await?;
205 let data = resp.into_data()?;
206
207 info!("关系状态数: {:?}", data);
208 assert_eq!(data.mid, TEST_MID);
209
210 Ok(())
211 }
212
213 #[tokio::test]
214 async fn test_get_up_stat() -> Result<(), BpiError> {
215 let bpi = BpiClient::new();
216 let resp = bpi.user_up_stat(TEST_UP_MID).await?;
217 let data = resp.into_data()?;
218
219 info!("UP主状态数: {:?}", data);
220 assert!(data.likes > 0);
221
222 Ok(())
223 }
224
225 #[tokio::test]
226 async fn test_get_nav_num() -> Result<(), BpiError> {
227 let bpi = BpiClient::new();
228 let resp = bpi.user_navnum(TEST_NAV_MID).await?;
229 let data = resp.into_data()?;
230
231 info!("用户导航栏状态数: {:?}", data);
232 assert!(data.video > 0);
233
234 Ok(())
235 }
236
237 #[tokio::test]
238 async fn test_get_album_count() -> Result<(), BpiError> {
239 let bpi = BpiClient::new();
240 let resp = bpi.user_album_count(TEST_NAV_MID).await?;
241 let data = resp.into_data()?;
242
243 info!("相簿投稿数: {:?}", data);
244 assert!(data.all_count > 0);
245
246 Ok(())
247 }
248}