From 7c106b7fdaa815c43010914ffb97e9ae772cd922 Mon Sep 17 00:00:00 2001 From: lanyeeee Date: Sun, 20 Jul 2025 05:24:08 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=90=8E=E7=AB=AF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E6=94=B6=E8=97=8F=E5=A4=B9=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/bili_client.rs | 45 +++++++++++++++++++++++++++--- src-tauri/src/commands.rs | 17 +++++++---- src-tauri/src/lib.rs | 1 + src-tauri/src/types/fav_folders.rs | 19 +++++++++++++ src-tauri/src/types/mod.rs | 1 + src/bindings.ts | 10 +++++++ 6 files changed, 84 insertions(+), 9 deletions(-) create mode 100644 src-tauri/src/types/fav_folders.rs diff --git a/src-tauri/src/bili_client.rs b/src-tauri/src/bili_client.rs index 4913aac..86d4efe 100644 --- a/src-tauri/src/bili_client.rs +++ b/src-tauri/src/bili_client.rs @@ -16,10 +16,11 @@ use crate::{ extensions::AppHandleExt, types::{ bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo, - cheese_media_url::CheeseMediaUrl, 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, + 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, }, }; @@ -424,6 +425,42 @@ impl BiliClient { Ok(player_info) } + pub async fn get_fav_folders(&self, uid: i64) -> anyhow::Result { + let params = json!({"up_mid": uid}); + // 发送获取收藏夹信息的请求 + let request = self + .api_client + .read() + .get("https://api.bilibili.com/x/v3/fav/folder/created/list-all") + .query(¶ms) + .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解析为FavFolders + let data_str = data.to_string(); + let fav_folders: FavFolders = serde_json::from_str(&data_str) + .context(format!("将data解析为FavFolders失败: {data_str}"))?; + + Ok(fav_folders) + } + + fn get_cookie(&self) -> String { let sessdata = self.app.get_config().read().sessdata.clone(); format!("SESSDATA={sessdata}") diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 02ae7cf..ef2cb42 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -7,11 +7,7 @@ use crate::{ extensions::AppHandleExt, logger, types::{ - bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo, - cheese_media_url::CheeseMediaUrl, 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, 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 }, }; @@ -187,3 +183,14 @@ pub async fn get_player_info(app: AppHandle, aid: i64, cid: i64) -> CommandResul .map_err(|err| CommandError::from("获取播放器信息失败", err))?; Ok(player_info) } + +#[tauri::command(async)] +#[specta::specta] +pub async fn get_fav_folders(app: AppHandle, uid: i64) -> CommandResult { + let bili_client = app.get_bili_client(); + let fav_folders = bili_client + .get_fav_folders(uid) + .await + .map_err(|err| CommandError::from("获取收藏夹列表失败", err))?; + Ok(fav_folders) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 42fa0f7..ceb4d73 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -37,6 +37,7 @@ pub fn run() { get_bangumi_url, get_cheese_url, get_player_info, + get_fav_folders, ]) .events(tauri_specta::collect_events![LogEvent]); diff --git a/src-tauri/src/types/fav_folders.rs b/src-tauri/src/types/fav_folders.rs new file mode 100644 index 0000000..2fe95d8 --- /dev/null +++ b/src-tauri/src/types/fav_folders.rs @@ -0,0 +1,19 @@ +use serde::{Deserialize, Serialize}; +use specta::Type; + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct FavFolders { + pub count: i64, + pub list: Vec, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct Folder { + pub id: i64, + pub fid: i64, + pub mid: i64, + pub attr: i64, + pub title: String, + pub fav_state: i64, + pub media_count: i64, +} diff --git a/src-tauri/src/types/mod.rs b/src-tauri/src/types/mod.rs index 0b47972..3662634 100644 --- a/src-tauri/src/types/mod.rs +++ b/src-tauri/src/types/mod.rs @@ -2,6 +2,7 @@ pub mod bangumi_info; pub mod bangumi_media_url; pub mod cheese_info; pub mod cheese_media_url; +pub mod fav_folders; pub mod get_bangumi_info_params; pub mod get_cheese_info_params; pub mod get_normal_info_params; diff --git a/src/bindings.ts b/src/bindings.ts index d97e1f3..1ece551 100644 --- a/src/bindings.ts +++ b/src/bindings.ts @@ -98,6 +98,14 @@ async getPlayerInfo(aid: number, cid: number) : Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_fav_folders", { uid }) }; +} catch (e) { + if(e instanceof Error) throw e; + else return { status: "error", error: e as any }; +} } } @@ -156,8 +164,10 @@ export type EpTag = { part_preview_tag: string; pay_tag: string; preview_tag: st export type Faq = { content: string; link: string; title: string } export type Faq1 = { items: Faq1Item[]; title: string } export type Faq1Item = { answer: string; question: string } +export type FavFolders = { count: number; list: Folder[] } export type Fawkes = { config_version: number; ff_version: number } export type Flac = { display: boolean; audio: MediaInNormal | null } +export type Folder = { id: number; fid: number; mid: number; attr: number; title: string; fav_state: number; media_count: number } export type GetBangumiInfoParams = { EpId: number } | { SeasonId: number } export type GetCheeseInfoParams = { EpId: number } | { SeasonId: number } export type GetNormalInfoParams = { Bvid: string } | { Aid: number }