bpi_rs/login/
login_notice.rs1use crate::{ BilibiliRequest, BpiClient, BpiError, BpiResponse };
2use serde::{ Deserialize, Serialize };
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, Deserialize, Serialize)]
9pub struct LoginNoticeData {
10 pub mid: u64,
11 pub device_name: String,
12 pub login_type: String,
13 pub login_time: String,
14 pub location: String,
15 pub ip: String,
16}
17
18#[derive(Debug, Clone, Deserialize, Serialize)]
20pub struct LoginLogData {
21 pub count: u32,
22 pub list: Vec<LoginLogEntry>,
23}
24
25#[derive(Debug, Clone, Deserialize, Serialize)]
27pub struct LoginLogEntry {
28 pub ip: String,
29 pub time: u64,
30 pub time_at: String,
31 pub status: bool,
32 #[serde(rename = "type")]
33 pub login_type: u8,
34 #[serde(rename = "geo")]
35 pub location: String,
36}
37
38impl BpiClient {
39 pub async fn login_notice(
45 &self,
46 mid: u64,
47 buvid: Option<&str>
48 ) -> Result<BpiResponse<LoginNoticeData>, BpiError> {
49 let mut params = HashMap::new();
50 params.insert("mid", mid.to_string());
51 if let Some(buvid_val) = buvid {
52 params.insert("buvid", buvid_val.to_string());
53 }
54
55 self
56 .get("https://api.bilibili.com/x/safecenter/login_notice")
57 .query(¶ms)
58 .send_bpi("查询登录记录").await
59 }
60
61 pub async fn login_log(&self) -> Result<BpiResponse<LoginLogData>, BpiError> {
66 self
67 .get("https://api.bilibili.com/x/member/web/login/log")
68 .query(
69 &[
70 ("jsonp", "jsonp"),
71 ("web_location", "333.33"),
72 ]
73 )
74 .send_bpi("查询最近一周登录情况").await
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use super::*;
81
82 #[tokio::test]
83 async fn test_get_login_notice() -> Result<(), BpiError> {
84 let bpi = BpiClient::new();
85 let mid = 4279370;
86
87 let resp = bpi.login_notice(mid, None).await?;
88 let data = resp.into_data()?;
89
90 println!("指定登录记录:");
91 println!(" 设备名: {}", data.device_name);
92 println!(" 登录方式: {}", data.login_type);
93 println!(" 登录时间: {}", data.login_time);
94 println!(" 登录位置: {}", data.location);
95 println!(" IP: {}", data.ip);
96
97 assert_eq!(data.mid, mid);
98
99 Ok(())
100 }
101
102 #[tokio::test]
103 async fn test_get_login_log() -> Result<(), BpiError> {
104 let bpi = BpiClient::new();
105
106 let resp = bpi.login_log().await?;
107 let data = resp.into_data()?;
108
109 println!("最近一周登录记录 (共 {} 条):", data.count);
110 for entry in data.list {
111 println!(" 时间: {} ({})", entry.time_at, entry.time);
112 println!(" IP: {}", entry.ip);
113 println!(" 位置: {}", entry.location);
114 println!(" 登录成功: {}", entry.status);
115 println!(" 登录类型: {}", entry.login_type);
116 }
117
118 Ok(())
119 }
120}