feat: 后端支持获取收藏夹内容

This commit is contained in:
lanyeeee
2025-07-20 05:24:24 +08:00
parent 7c106b7fda
commit a5d4d54335
7 changed files with 189 additions and 6 deletions
+44 -5
View File
@@ -16,11 +16,11 @@ use crate::{
extensions::AppHandleExt,
types::{
bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo,
cheese_media_url::CheeseMediaUrl, fav_folders::FavFolders,
cheese_media_url::CheeseMediaUrl, fav_folders::FavFolders, fav_info::FavInfo,
get_bangumi_info_params::GetBangumiInfoParams, get_cheese_info_params::GetCheeseInfoParams,
get_normal_info_params::GetNormalInfoParams, normal_info::NormalInfo,
normal_media_url::NormalMediaUrl, player_info::PlayerInfo, qrcode_data::QrcodeData,
qrcode_status::QrcodeStatus, user_info::UserInfo,
get_fav_info_params::GetFavInfoParams, get_normal_info_params::GetNormalInfoParams,
normal_info::NormalInfo, normal_media_url::NormalMediaUrl, player_info::PlayerInfo,
qrcode_data::QrcodeData, qrcode_status::QrcodeStatus, user_info::UserInfo,
},
};
@@ -459,7 +459,46 @@ impl BiliClient {
Ok(fav_folders)
}
pub async fn get_fav_info(&self, params: GetFavInfoParams) -> anyhow::Result<FavInfo> {
let params = json!({
"media_id": params.media_list_id,
"pn": params.pn,
"ps": 36,
"platform": "web",
});
// 发送获取收藏夹信息的请求
let request = self
.api_client
.read()
.get("https://api.bilibili.com/x/v3/fav/resource/list")
.query(&params)
.header("cookie", self.get_cookie());
let http_resp = request.send().await?;
// 检查http响应状态码
let status = http_resp.status();
let body = http_resp.text().await?;
if status != StatusCode::OK {
return Err(anyhow!("预料之外的状态码({status}): {body}"));
}
// 尝试将body解析为BiliResp
let bili_resp: BiliResp =
serde_json::from_str(&body).context(format!("将body解析为BiliResp失败: {body}"))?;
// 检查BiliResp的code字段
if bili_resp.code != 0 {
return Err(anyhow!("预料之外的code: {bili_resp:?}"));
}
// 检查BiliResp的data是否存在
let Some(data) = bili_resp.data else {
return Err(anyhow!("BiliResp中不存在data字段: {bili_resp:?}"));
};
// 尝试将data解析为FavInfo
let data_str = data.to_string();
let fav_info: FavInfo = serde_json::from_str(&data_str)
.context(format!("将data解析为FavInfo失败: {data_str}"))?;
Ok(fav_info)
}
fn get_cookie(&self) -> String {
let sessdata = self.app.get_config().read().sessdata.clone();
+17 -1
View File
@@ -7,7 +7,12 @@ use crate::{
extensions::AppHandleExt,
logger,
types::{
bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo, cheese_media_url::CheeseMediaUrl, fav_folders::FavFolders, get_bangumi_info_params::GetBangumiInfoParams, get_cheese_info_params::GetCheeseInfoParams, get_normal_info_params::GetNormalInfoParams, normal_info::NormalInfo, normal_media_url::NormalMediaUrl, player_info::PlayerInfo, qrcode_data::QrcodeData, qrcode_status::QrcodeStatus, user_info::UserInfo
bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo,
cheese_media_url::CheeseMediaUrl, fav_folders::FavFolders, fav_info::FavInfo,
get_bangumi_info_params::GetBangumiInfoParams, get_cheese_info_params::GetCheeseInfoParams,
get_fav_info_params::GetFavInfoParams, get_normal_info_params::GetNormalInfoParams,
normal_info::NormalInfo, normal_media_url::NormalMediaUrl, player_info::PlayerInfo,
qrcode_data::QrcodeData, qrcode_status::QrcodeStatus, user_info::UserInfo,
},
};
@@ -194,3 +199,14 @@ pub async fn get_fav_folders(app: AppHandle, uid: i64) -> CommandResult<FavFolde
.map_err(|err| CommandError::from("获取收藏夹列表失败", err))?;
Ok(fav_folders)
}
#[tauri::command(async)]
#[specta::specta]
pub async fn get_fav_info(app: AppHandle, params: GetFavInfoParams) -> CommandResult<FavInfo> {
let bili_client = app.get_bili_client();
let fav_info = bili_client
.get_fav_info(params)
.await
.map_err(|err| CommandError::from("获取收藏夹内容失败", err))?;
Ok(fav_info)
}
+1
View File
@@ -38,6 +38,7 @@ pub fn run() {
get_cheese_url,
get_player_info,
get_fav_folders,
get_fav_info,
])
.events(tauri_specta::collect_events![LogEvent]);
+100
View File
@@ -0,0 +1,100 @@
use serde::{Deserialize, Serialize};
use specta::Type;
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct FavInfo {
pub info: Info,
pub medias: Option<Vec<MediaInFav>>,
pub has_more: bool,
pub ttl: i64,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
#[allow(clippy::struct_field_names)]
pub struct Info {
pub id: i64,
pub fid: i64,
pub mid: i64,
pub attr: i64,
pub title: String,
pub cover: String,
pub upper: Upper,
pub cover_type: i64,
pub cnt_info: CntInfo,
#[serde(rename = "type")]
pub type_field: i64,
pub intro: String,
pub ctime: i64,
pub mtime: i64,
pub state: i64,
pub fav_state: i64,
pub like_state: i64,
pub media_count: i64,
pub is_top: bool,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct Upper {
pub mid: i64,
pub name: String,
pub face: String,
pub followed: bool,
pub vip_type: i64,
pub vip_statue: i64,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct CntInfo {
pub collect: i64,
pub play: i64,
pub thumb_up: i64,
pub share: i64,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
#[allow(clippy::struct_field_names)]
pub struct MediaInFav {
pub id: i64,
#[serde(rename = "type")]
pub type_field: i64,
pub title: String,
pub cover: String,
pub intro: String,
pub page: i64,
pub duration: u64,
pub upper: UpperInMedia,
pub attr: i64,
pub cnt_info: CntInfoInMedia,
pub link: String,
pub ctime: i64,
pub pubtime: i64,
pub fav_time: i64,
pub bv_id: String,
pub bvid: String,
pub ugc: Option<Ugc>,
pub media_list_link: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct UpperInMedia {
pub mid: i64,
pub name: String,
pub face: String,
pub jump_link: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct CntInfoInMedia {
pub collect: i64,
pub play: i64,
pub danmaku: i64,
pub vt: i64,
pub play_switch: i64,
pub reply: i64,
pub view_text_1: String,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct Ugc {
pub first_cid: i64,
}
@@ -0,0 +1,8 @@
use serde::{Deserialize, Serialize};
use specta::Type;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
pub struct GetFavInfoParams {
pub media_list_id: i64,
pub pn: i64,
}
+2
View File
@@ -3,8 +3,10 @@ pub mod bangumi_media_url;
pub mod cheese_info;
pub mod cheese_media_url;
pub mod fav_folders;
pub mod fav_info;
pub mod get_bangumi_info_params;
pub mod get_cheese_info_params;
pub mod get_fav_info_params;
pub mod get_normal_info_params;
pub mod log_level;
pub mod normal_info;