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(
123 &self,
124 vmid: u64,
125 ) -> Result<BpiResponse<RelationStatResponseData>, BpiError> {
126 self.get("https://api.bilibili.com/x/relation/stat")
127 .query(&[("vmid", &vmid.to_string())])
128 .send_bpi("获取用户关系状态数")
129 .await
130 }
131
132 pub async fn user_up_stat(
141 &self,
142 mid: u64,
143 ) -> Result<BpiResponse<UpstatResponseData>, BpiError> {
144 self.get("https://api.bilibili.com/x/space/upstat")
145 .query(&[("mid", &mid.to_string())])
146 .send_bpi("获取 UP 主状态数")
147 .await
148 }
149
150 pub async fn user_navnum(&self, mid: u64) -> Result<BpiResponse<NavnumResponseData>, BpiError> {
159 self.get("https://api.bilibili.com/x/space/navnum")
160 .query(&[("mid", &mid.to_string())])
161 .send_bpi("获取用户导航栏状态数")
162 .await
163 }
164
165 pub async fn user_album_count(
174 &self,
175 uid: u64,
176 ) -> Result<BpiResponse<AlbumCountResponseData>, BpiError> {
177 self.get("https://api.vc.bilibili.com/link_draw/v1/doc/upload_count")
178 .query(&[("uid", &uid.to_string())])
179 .send_bpi("获取相簿投稿数")
180 .await
181 }
182}
183
184#[cfg(test)]
187mod tests {
188 use super::*;
189 use tracing::info;
190
191 const TEST_MID: u64 = 332704117;
194 const TEST_UP_MID: u64 = 456664753;
195 const TEST_NAV_MID: u64 = 645769214;
196
197 #[tokio::test]
198
199 async fn test_get_relation_stat() -> Result<(), BpiError> {
200 let bpi = BpiClient::new();
201 let resp = bpi.user_relation_stat(TEST_MID).await?;
202 let data = resp.into_data()?;
203
204 info!("关系状态数: {:?}", data);
205 assert_eq!(data.mid, TEST_MID);
206
207 Ok(())
208 }
209
210 #[tokio::test]
211
212 async fn test_get_up_stat() -> Result<(), BpiError> {
213 let bpi = BpiClient::new();
214 let resp = bpi.user_up_stat(TEST_UP_MID).await?;
215 let data = resp.into_data()?;
216
217 info!("UP主状态数: {:?}", data);
218 assert!(data.likes > 0);
219
220 Ok(())
221 }
222
223 #[tokio::test]
224 async fn test_get_nav_num() -> Result<(), BpiError> {
225 let bpi = BpiClient::new();
226 let resp = bpi.user_navnum(TEST_NAV_MID).await?;
227 let data = resp.into_data()?;
228
229 info!("用户导航栏状态数: {:?}", data);
230 assert!(data.video > 0);
231
232 Ok(())
233 }
234
235 #[tokio::test]
236 async fn test_get_album_count() -> Result<(), BpiError> {
237 let bpi = BpiClient::new();
238 let resp = bpi.user_album_count(TEST_NAV_MID).await?;
239 let data = resp.into_data()?;
240
241 info!("相簿投稿数: {:?}", data);
242 assert!(data.all_count > 0);
243
244 Ok(())
245 }
246}