From e1088cb8f5474328a28ca2955108c9cf0a6b60fc Mon Sep 17 00:00:00 2001 From: lanyeeee Date: Wed, 20 Aug 2025 05:19:40 +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=E8=BF=BD=E7=95=AA=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/bili_client.rs | 48 +++- src-tauri/src/commands.rs | 16 ++ src-tauri/src/lib.rs | 1 + src-tauri/src/types/bangumi_follow_info.rs | 207 ++++++++++++++++++ src-tauri/src/types/bangumi_info.rs | 22 +- .../types/get_bangumi_follow_info_params.rs | 13 ++ src-tauri/src/types/mod.rs | 2 + src/bindings.ts | 46 +++- 8 files changed, 335 insertions(+), 20 deletions(-) create mode 100644 src-tauri/src/types/bangumi_follow_info.rs create mode 100644 src-tauri/src/types/get_bangumi_follow_info_params.rs diff --git a/src-tauri/src/bili_client.rs b/src-tauri/src/bili_client.rs index 4303ea6..1331f79 100644 --- a/src-tauri/src/bili_client.rs +++ b/src-tauri/src/bili_client.rs @@ -21,8 +21,10 @@ use crate::{ extensions::{AnyhowErrorToStringChain, AppHandleExt}, protobuf::DmSegMobileReply, types::{ - bangumi_info::BangumiInfo, bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo, + bangumi_follow_info::BangumiFollowInfo, bangumi_info::BangumiInfo, + bangumi_media_url::BangumiMediaUrl, cheese_info::CheeseInfo, cheese_media_url::CheeseMediaUrl, fav_folders::FavFolders, fav_info::FavInfo, + get_bangumi_follow_info_params::GetBangumiFollowInfoParams, get_bangumi_info_params::GetBangumiInfoParams, get_cheese_info_params::GetCheeseInfoParams, get_fav_info_params::GetFavInfoParams, get_normal_info_params::GetNormalInfoParams, get_user_video_info_params::GetUserVideoInfoParams, normal_info::NormalInfo, @@ -626,6 +628,50 @@ impl BiliClient { Ok(watch_later_info) } + pub async fn get_bangumi_follow_info( + &self, + params: GetBangumiFollowInfoParams, + ) -> anyhow::Result { + // 发送获取番剧追踪信息的请求 + let params = json!({ + "vmid": params.vmid, + "type": params.type_field, + "pn": params.pn, + "ps": 24, + "follow_status": params.follow_status, + }); + let request = self + .api_client + .read() + .get("https://api.bilibili.com/x/space/bangumi/follow/list") + .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解析为BangumiFollowInfo + let data_str = data.to_string(); + let bangumi_follow_info: BangumiFollowInfo = serde_json::from_str(&data_str) + .context(format!("将data解析为BangumiFollowInfo失败: {data_str}"))?; + + Ok(bangumi_follow_info) + } + pub async fn get_media_chunk( &self, media_url: &str, diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 3667fdd..a71fed7 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -9,10 +9,12 @@ use crate::{ extensions::AppHandleExt, logger, types::{ + bangumi_follow_info::BangumiFollowInfo, bangumi_info::EpInBangumi, create_download_task_params::CreateDownloadTaskParams, fav_folders::FavFolders, fav_info::FavInfo, + get_bangumi_follow_info_params::GetBangumiFollowInfoParams, get_bangumi_info_params::GetBangumiInfoParams, get_cheese_info_params::GetCheeseInfoParams, get_fav_info_params::GetFavInfoParams, @@ -179,6 +181,20 @@ pub async fn get_watch_later_info(app: AppHandle, page: i32) -> CommandResult CommandResult { + let bili_client = app.get_bili_client(); + let bangumi_follow_info = bili_client + .get_bangumi_follow_info(params) + .await + .map_err(|err| CommandError::from("获取追番信息失败", err))?; + Ok(bangumi_follow_info) +} + #[allow(clippy::needless_pass_by_value)] #[tauri::command(async)] #[specta::specta] diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 53c5c3c..b732be8 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -44,6 +44,7 @@ pub fn run() { get_fav_folders, get_fav_info, get_watch_later_info, + get_bangumi_follow_info, create_download_tasks, pause_download_tasks, resume_download_tasks, diff --git a/src-tauri/src/types/bangumi_follow_info.rs b/src-tauri/src/types/bangumi_follow_info.rs new file mode 100644 index 0000000..94580a3 --- /dev/null +++ b/src-tauri/src/types/bangumi_follow_info.rs @@ -0,0 +1,207 @@ +use serde::{Deserialize, Serialize}; +use specta::Type; + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct BangumiFollowInfo { + pub list: Vec, + pub pn: i64, + pub ps: i64, + pub total: i64, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct EpInBangumiFollow { + pub season_id: i64, + pub media_id: i64, + pub season_type: i64, + pub season_type_name: String, + pub title: String, + pub cover: String, + pub total_count: i64, + pub is_finish: i64, + pub is_started: i64, + pub is_play: i64, + pub badge: String, + pub badge_type: i64, + pub rights: RightsInBangumiFollow, + pub stat: StatInBangumiFollow, + pub new_ep: NewEpInBangumiFollow, + pub rating: Option, + pub square_cover: String, + pub season_status: i64, + pub season_title: String, + pub badge_ep: String, + pub media_attr: i64, + pub season_attr: i64, + pub evaluate: String, + pub areas: Vec, + pub subtitle: String, + pub first_ep: i64, + pub can_watch: i64, + pub release_date_show: Option, + pub series: SeriesInBangumiFollow, + pub publish: PublishInBangumiFollow, + pub mode: i64, + pub section: Vec, + pub url: String, + pub badge_info: BadgeInfoInBangumiFollow, + pub renewal_time: Option, + pub first_ep_info: FirstEpInfo, + pub formal_ep_count: Option, + pub short_url: String, + pub badge_infos: Option, + pub season_version: Option, + pub horizontal_cover_16_9: Option, + pub horizontal_cover_16_10: Option, + pub subtitle_14: Option, + pub viewable_crowd_type: i64, + #[serde(default)] + pub producers: Vec, + pub summary: String, + #[serde(default)] + pub styles: Vec, + pub follow_status: i64, + pub is_new: i64, + pub progress: String, + pub both_follow: bool, + pub subtitle_25: Option, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct RightsInBangumiFollow { + pub allow_review: Option, + pub allow_preview: Option, + pub is_selection: i64, + pub selection_style: i64, + pub is_rcmd: Option, + pub allow_bp_rank: Option, + pub allow_bp: Option, + pub allow_download: Option, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct StatInBangumiFollow { + pub follow: i64, + pub view: i64, + pub danmaku: i64, + pub reply: i64, + pub coin: i64, + pub series_follow: Option, + pub series_view: Option, + pub likes: i64, + pub favorite: i64, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct NewEpInBangumiFollow { + pub id: Option, + pub index_show: Option, + pub cover: Option, + pub title: Option, + pub long_title: Option, + pub pub_time: Option, + pub duration: Option, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct RatingInBangumiFollow { + pub score: f64, + pub count: i64, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct AreaInBangumiFollow { + pub id: i64, + pub name: String, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct SeriesInBangumiFollow { + pub series_id: Option, + pub title: Option, + pub season_count: Option, + pub new_season_id: Option, + pub series_ord: Option, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct PublishInBangumiFollow { + pub pub_time: String, + pub pub_time_show: String, + pub release_date: String, + pub release_date_show: String, + pub pub_time_show_db: Option, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct SectionInBangumiFollow { + pub section_id: i64, + pub season_id: i64, + pub limit_group: i64, + pub watch_platform: i64, + pub copyright: String, + pub ban_area_show: i64, + pub episode_ids: Vec, + #[serde(rename = "type")] + pub type_field: Option, + pub title: Option, + pub attr: Option, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct BadgeInfoInBangumiFollow { + pub text: Option, + pub bg_color: String, + pub bg_color_night: String, + pub img: Option, + pub multi_img: MultiImg, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct MultiImg { + pub color: String, + pub medium_remind: String, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct FirstEpInfo { + pub id: i64, + pub cover: String, + pub title: String, + pub long_title: Option, + pub pub_time: String, + pub duration: i64, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct BadgeInfos { + pub vip_or_pay: Option, + pub content_attr: Option, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct VipOrPay { + pub text: String, + pub bg_color: String, + pub bg_color_night: String, + pub img: String, + pub multi_img: MultiImg, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct ContentAttr { + pub text: String, + pub bg_color: String, + pub bg_color_night: String, + pub img: String, + pub multi_img: MultiImg, +} + +#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct Producer { + pub mid: i64, + #[serde(rename = "type")] + pub type_field: i64, + pub is_contribute: Option, + pub title: String, +} diff --git a/src-tauri/src/types/bangumi_info.rs b/src-tauri/src/types/bangumi_info.rs index 5a95ae7..abe39c6 100644 --- a/src-tauri/src/types/bangumi_info.rs +++ b/src-tauri/src/types/bangumi_info.rs @@ -7,7 +7,7 @@ pub struct BangumiInfo { pub activity: Activity, pub actors: String, pub alias: String, - pub areas: Vec, + pub areas: Vec, pub bkg_cover: String, pub cover: String, pub delivery_fragment_video: bool, @@ -24,15 +24,15 @@ pub struct BangumiInfo { pub payment: Option, pub play_strategy: Option, pub positive: Positive, - pub publish: Publish, - pub rating: Option, + pub publish: PublishInBangumi, + pub rating: Option, pub record: String, pub rights: RightsInBangumi, pub season_id: i64, pub season_title: String, pub seasons: Vec, pub section: Option>, - pub series: Series, + pub series: SeriesInBangumi, pub share_copy: String, pub share_sub_title: String, pub share_url: String, @@ -95,7 +95,7 @@ pub struct Activity { } #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] -pub struct Area { +pub struct AreaInBangumi { pub id: i64, pub name: String, } @@ -105,7 +105,7 @@ pub struct Area { pub struct EpInBangumi { pub aid: i64, pub badge: String, - pub badge_info: BadgeInfo, + pub badge_info: BadgeInfoInBangumi, pub badge_type: Option, pub bvid: Option, pub cid: i64, @@ -140,7 +140,7 @@ pub struct EpInBangumi { } #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] -pub struct BadgeInfo { +pub struct BadgeInfoInBangumi { pub bg_color: String, pub bg_color_night: String, pub text: String, @@ -228,7 +228,7 @@ pub struct Positive { } #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] -pub struct Publish { +pub struct PublishInBangumi { pub is_finish: i64, pub is_started: i64, pub pub_time: String, @@ -238,7 +238,7 @@ pub struct Publish { } #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] -pub struct Rating { +pub struct RatingInBangumi { pub count: i64, pub score: f64, } @@ -266,7 +266,7 @@ pub struct RightsInBangumi { #[allow(clippy::struct_field_names)] pub struct Season { pub badge: String, - pub badge_info: BadgeInfo, + pub badge_info: BadgeInfoInBangumi, pub badge_type: i64, pub cover: String, pub enable_vt: bool, @@ -298,7 +298,7 @@ pub struct StatInSeason { #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize, Type)] #[allow(clippy::struct_field_names)] -pub struct Series { +pub struct SeriesInBangumi { pub display_type: i64, pub series_id: i64, pub series_title: String, diff --git a/src-tauri/src/types/get_bangumi_follow_info_params.rs b/src-tauri/src/types/get_bangumi_follow_info_params.rs new file mode 100644 index 0000000..2e61fbe --- /dev/null +++ b/src-tauri/src/types/get_bangumi_follow_info_params.rs @@ -0,0 +1,13 @@ +use serde::{Deserialize, Serialize}; +use specta::Type; + +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Type)] +pub struct GetBangumiFollowInfoParams { + pub vmid: i64, + /// 1: 番剧 2: 电视剧或电影 + #[serde(rename = "type")] + pub type_field: i64, + pub pn: i64, + // 0: 全部 1: 想看 2: 在看 3: 看过 + pub follow_status: i64, +} diff --git a/src-tauri/src/types/mod.rs b/src-tauri/src/types/mod.rs index a2cd515..ad34195 100644 --- a/src-tauri/src/types/mod.rs +++ b/src-tauri/src/types/mod.rs @@ -1,4 +1,5 @@ pub mod audio_quality; +pub mod bangumi_follow_info; pub mod bangumi_info; pub mod bangumi_media_url; pub mod cheese_info; @@ -7,6 +8,7 @@ pub mod codec_type; pub mod create_download_task_params; pub mod fav_folders; pub mod fav_info; +pub mod get_bangumi_follow_info_params; pub mod get_bangumi_info_params; pub mod get_cheese_info_params; pub mod get_fav_info_params; diff --git a/src/bindings.ts b/src/bindings.ts index aa49acf..b5a91de 100644 --- a/src/bindings.ts +++ b/src/bindings.ts @@ -80,6 +80,14 @@ async getWatchLaterInfo(page: number) : Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_bangumi_follow_info", { params }) }; +} catch (e) { + if(e instanceof Error) throw e; + else return { status: "error", error: e as any }; +} +}, async createDownloadTasks(params: CreateDownloadTaskParams) : Promise { await TAURI_INVOKE("create_download_tasks", { params }); }, @@ -149,13 +157,17 @@ logEvent: "log-event" export type AbtestInfo = { style_abtest: number } export type Activity = { head_bg_url: string; id: number; title: string } export type Arc = { aid: number; videos: number; type_id: number; type_name: string; copyright: number; pic: string; title: string; pubdate: number; ctime: number; desc: string; state: number; duration: number; rights: RightsInNormalEp; author: Author; stat: StatInNormalEp; dynamic: string; dimension: Dimension; is_chargeable_season: boolean; is_blooper: boolean; enable_vt: number; vt_display: string; type_id_v2: number; type_name_v2: string; is_lesson_video: number } -export type Area = { id: number; name: string } +export type AreaInBangumi = { id: number; name: string } +export type AreaInBangumiFollow = { id: number; name: string } export type ArgueInfo = { argue_msg: string; argue_type: number; argue_link: string } export type AudioQuality = "Unknown" | "64K" | "132K" | "192K" | "Dolby" | "HiRes" export type AudioTask = { selected: boolean; url: string; audio_quality: AudioQuality; content_length: number; chunks: MediaChunk[]; completed: boolean } export type Author = { mid: number; name: string; face: string } -export type BadgeInfo = { bg_color: string; bg_color_night: string; text: string } -export type BangumiInfo = { activity: Activity; actors: string; alias: string; areas: Area[]; bkg_cover: string; cover: string; delivery_fragment_video: boolean; enable_vt: boolean; episodes: EpInBangumi[]; evaluate: string; hide_ep_vv_vt_dm: number; icon_font: IconFont; jp_title: string; link: string; media_id: number; mode: number; new_ep: NewEp; payment: PaymentInBangumi | null; play_strategy: PlayStrategy | null; positive: Positive; publish: Publish; rating: Rating | null; record: string; rights: RightsInBangumi; season_id: number; season_title: string; seasons: Season[]; section: SectionInBangumi[] | null; series: Series; share_copy: string; share_sub_title: string; share_url: string; show: Show; show_season_type: number; square_cover: string; staff: string; stat: StatInBangumi; status: number; styles: string[]; subtitle: string; title: string; total: number; type: number; up_info: UpInfoInBangumi | null; user_status: UserStatusInBangumi } +export type BadgeInfoInBangumi = { bg_color: string; bg_color_night: string; text: string } +export type BadgeInfoInBangumiFollow = { text: string | null; bg_color: string; bg_color_night: string; img: string | null; multi_img: MultiImg } +export type BadgeInfos = { vip_or_pay: VipOrPay | null; content_attr: ContentAttr | null } +export type BangumiFollowInfo = { list: EpInBangumiFollow[]; pn: number; ps: number; total: number } +export type BangumiInfo = { activity: Activity; actors: string; alias: string; areas: AreaInBangumi[]; bkg_cover: string; cover: string; delivery_fragment_video: boolean; enable_vt: boolean; episodes: EpInBangumi[]; evaluate: string; hide_ep_vv_vt_dm: number; icon_font: IconFont; jp_title: string; link: string; media_id: number; mode: number; new_ep: NewEp; payment: PaymentInBangumi | null; play_strategy: PlayStrategy | null; positive: Positive; publish: PublishInBangumi; rating: RatingInBangumi | null; record: string; rights: RightsInBangumi; season_id: number; season_title: string; seasons: Season[]; section: SectionInBangumi[] | null; series: SeriesInBangumi; share_copy: string; share_sub_title: string; share_url: string; show: Show; show_season_type: number; square_cover: string; staff: string; stat: StatInBangumi; status: number; styles: string[]; subtitle: string; title: string; total: number; type: number; up_info: UpInfoInBangumi | null; user_status: UserStatusInBangumi } export type BangumiSearchResult = { ep: EpInBangumi | null; info: BangumiInfo } export type Brief = { content: string; img: Img[]; title: string; type: number } export type CanvasConfig = { @@ -221,6 +233,7 @@ export type CodecType = "Unknown" | "Audio" | "AVC" | "HEVC" | "AV1" export type CommandError = { err_title: string; err_message: string } export type Config = { download_dir: string; enable_file_logger: boolean; sessdata: string; prefer_video_quality: PreferVideoQuality; prefer_codec_type: PreferCodecType; prefer_audio_quality: PreferAudioQuality; download_video: boolean; download_audio: boolean; auto_merge: boolean; download_xml_danmaku: boolean; download_ass_danmaku: boolean; download_json_danmaku: boolean; download_subtitle: boolean; download_cover: boolean; download_nfo: boolean; download_json: boolean; dir_fmt: string; dir_fmt_for_part: string; time_fmt: string; proxy_mode: ProxyMode; proxy_host: string; proxy_port: number; task_concurrency: number; task_download_interval_sec: number; chunk_concurrency: number; chunk_download_interval_sec: number; danmaku_config: CanvasConfig } export type Consulting = { consulting_flag: boolean; consulting_url: string } +export type ContentAttr = { text: string; bg_color: string; bg_color_night: string; img: string; multi_img: MultiImg } export type ContentList = { bold: boolean; content: string; number: string } export type Cooperation = { link: string } export type CoverTask = { selected: boolean; url: string; completed: boolean } @@ -237,7 +250,8 @@ export type DownloadEvent = { event: "Speed"; data: { speed: string } } | { even export type DownloadProgress = { task_id: string; episode_type: EpisodeType; aid: number; bvid: string | null; cid: number; ep_id: number | null; duration: number; pub_ts: number; collection_title: string; part_title: string | null; part_order: number | null; episode_title: string; episode_order: number; up_name: string | null; up_uid: number | null; up_avatar: string | null; episode_dir: string; filename: string; video_task: VideoTask; audio_task: AudioTask; merge_task: MergeTask; subtitle_task: SubtitleTask; danmaku_task: DanmakuTask; cover_task: CoverTask; nfo_task: NfoTask; json_task: JsonTask; create_ts: number; completed_ts: number | null } export type DownloadTaskState = "Pending" | "Downloading" | "Paused" | "Completed" | "Failed" export type Ed = { end: number; start: number } -export type EpInBangumi = { aid: number; badge: string; badge_info: BadgeInfo; badge_type: number | null; bvid: string | null; cid: number; cover: string; dimension: DimensionInBangumi | null; duration: number | null; enable_vt: boolean; ep_id: number; from: string | null; id: number; is_view_hide: boolean; link: string; link_type: string | null; long_title: string | null; pub_time: number; pv: number; release_date: string | null; rights: RightsInBangumiEp | null; section_type: number; share_copy: string | null; share_url: string | null; short_link: string | null; showDrmLoginDialog: boolean; show_title: string | null; skip: Skip | null; status: number; subtitle: string | null; title: string; vid: string | null; icon_font: IconFont | null } +export type EpInBangumi = { aid: number; badge: string; badge_info: BadgeInfoInBangumi; badge_type: number | null; bvid: string | null; cid: number; cover: string; dimension: DimensionInBangumi | null; duration: number | null; enable_vt: boolean; ep_id: number; from: string | null; id: number; is_view_hide: boolean; link: string; link_type: string | null; long_title: string | null; pub_time: number; pv: number; release_date: string | null; rights: RightsInBangumiEp | null; section_type: number; share_copy: string | null; share_url: string | null; short_link: string | null; showDrmLoginDialog: boolean; show_title: string | null; skip: Skip | null; status: number; subtitle: string | null; title: string; vid: string | null; icon_font: IconFont | null } +export type EpInBangumiFollow = { season_id: number; media_id: number; season_type: number; season_type_name: string; title: string; cover: string; total_count: number; is_finish: number; is_started: number; is_play: number; badge: string; badge_type: number; rights: RightsInBangumiFollow; stat: StatInBangumiFollow; new_ep: NewEpInBangumiFollow; rating: RatingInBangumiFollow | null; square_cover: string; season_status: number; season_title: string; badge_ep: string; media_attr: number; season_attr: number; evaluate: string; areas: AreaInBangumiFollow[]; subtitle: string; first_ep: number; can_watch: number; release_date_show: string | null; series: SeriesInBangumiFollow; publish: PublishInBangumiFollow; mode: number; section: SectionInBangumiFollow[]; url: string; badge_info: BadgeInfoInBangumiFollow; renewal_time: string | null; first_ep_info: FirstEpInfo; formal_ep_count: number | null; short_url: string; badge_infos: BadgeInfos | null; season_version: string | null; horizontal_cover_16_9: string | null; horizontal_cover_16_10: string | null; subtitle_14: string | null; viewable_crowd_type: number; producers?: Producer[]; summary: string; styles?: string[]; follow_status: number; is_new: number; progress: string; both_follow: boolean; subtitle_25: string | null } export type EpInCheese = { aid: number; catalogue_index: number; cid: number; cover: string; duration: number; ep_status: number; episode_can_view: boolean; from: string; id: number; index: number; label: string | null; page: number; play: number; play_way: number; playable: boolean; release_date: number; show_vt: boolean; status: number; subtitle: string; title: string; watched: boolean; watchedHistory: number } export type EpInNormal = { season_id: number; section_id: number; id: number; aid: number; cid: number; title: string; attribute: number; arc: Arc; page: PageInNormalEp; bvid: string; pages: PageInNormalEp[] } export type EpInUserVideo = { comment: number; typeid: number; play: number; pic: string; subtitle: string; description: string; copyright: string; title: string; review: number; author: string; mid: number; created: number; length: string; video_review: number; aid: number; bvid: string; hide_click: boolean; is_pay: number; is_union_video: number; is_steins_gate: number; is_live_playback: number; is_lesson_video: number; is_lesson_finished: number; lesson_update_info: string; jump_url: string; meta: MetaInUserVideo | null; is_avoided: number; season_id: number; attribute: number; is_charging_arc: boolean; elec_arc_type: number; elec_arc_badge: string; vt: number; enable_vt: number; vt_display: string; playback_position: number; is_self_view: boolean } @@ -250,7 +264,13 @@ export type Faq1Item = { answer: string; question: string } export type FavFolders = { count: number; list: Folder[] } export type FavInfo = { info: Info; medias: MediaInFav[] | null; has_more: boolean; ttl: number } export type FavSearchResult = FavInfo +export type FirstEpInfo = { id: number; cover: string; title: string; long_title: string | null; pub_time: string; duration: number } export type Folder = { id: number; fid: number; mid: number; attr: number; title: string; fav_state: number; media_count: number } +export type GetBangumiFollowInfoParams = { vmid: number; +/** + * 1: 番剧 2: 电视剧或电影 + */ +type: number; pn: number; follow_status: number } export type GetBangumiInfoParams = { EpId: number } | { SeasonId: number } export type GetCheeseInfoParams = { EpId: number } | { SeasonId: number } export type GetFavInfoParams = { media_list_id: number; pn: number } @@ -272,7 +292,9 @@ export type MediaInFav = { id: number; type: number; title: string; cover: strin export type MediaInWatchLater = { aid: number; videos: number; tid: number; tname: string; copyright: number; pic: string; title: string; pubdate: number; ctime: number; desc: string; state: number; duration: number; redirect_url: string | null; mission_id: number | null; rights: RightsInWatchLater; owner: OwnerInWatchLater; stat: StatInWatchLater; dynamic: string; dimension: DimensionInWatchLater; short_link_v2: string; up_from_v2: number | null; first_frame: string | null; pub_location: string | null; cover43: string; tidv2: number; tnamev2: string; pid_v2: number; pid_name_v2: string; page: PageInWatchLater; count: number; cid: number; progress: number; add_at: number; bvid: string; uri: string; enable_vt: number; view_text_1: string; card_type: number; left_icon_type: number; left_text: string; right_icon_type: number; right_text: string; arc_state: number; pgc_label: string; show_up: boolean; forbid_fav: boolean; forbid_sort: boolean; season_title: string; long_title: string; index_title: string; c_source: string; season_id: number | null } export type MergeTask = { selected: boolean; completed: boolean } export type MetaInUserVideo = { id: number; title: string; cover: string; mid: number; intro: string; sign_state: number; attribute: number; stat: StatInUserVideo; ep_count: number; first_aid: number; ptime: number; ep_num: number } +export type MultiImg = { color: string; medium_remind: string } export type NewEp = { desc: string; id: number; is_new: number; title: string } +export type NewEpInBangumiFollow = { id: number | null; index_show: string | null; cover: string | null; title: string | null; long_title: string | null; pub_time: string | null; duration: number | null } export type NewEpInSeason = { cover: string; id: number; index_show: string } export type NfoTask = { selected: boolean; completed: boolean } export type NormalInfo = { bvid: string; aid: number; videos: number; tid: number; tid_v2: number; tname: string; tname_v2: string; copyright: number; pic: string; title: string; pubdate: number; ctime: number; desc: string; desc_v2: DescV2[] | null; state: number; duration: number; rights: Rights; owner: OwnerInNormal; stat: StatInNormal; argue_info: ArgueInfo; dynamic: string; cid: number; dimension: Dimension; teenage_mode: number; is_chargeable_season: boolean; is_story: boolean; is_upower_exclusive: boolean; is_upower_play: boolean; is_upower_preview: boolean; enable_vt: number; vt_display: string; is_upower_exclusive_with_qa: boolean; no_cache: boolean; pages: PageInNormal[]; subtitle: SubtitleInNormal; staff: Staff[] | null; ugc_season: UgcSeason | null; is_season_display: boolean; user_garb: UserGarb; honor_reply: HonorReply; like_icon: string; need_jump_bv: boolean; disable_show_up_info: boolean; is_story_play: number; is_view_self: boolean } @@ -298,30 +320,37 @@ export type PreferAudioQuality = "Best" | "64K" | "132K" | "192K" | "Dolby" | "H export type PreferCodecType = "Unknown" | "AVC" | "HEVC" | "AV1" export type PreferVideoQuality = "Best" | "240P" | "360P" | "480P" | "720P" | "720P60" | "1080P" | "AiRepair" | "1080P+" | "1080P60" | "4K" | "HDR" | "Dolby" | "8K" export type PreviewedPurchaseNote = { long_watch_text: string; pay_text: string; price_format: string; watch_text: string; watching_text: string } +export type Producer = { mid: number; type: number; is_contribute: number | null; title: string } export type ProxyMode = "NoProxy" | "System" | "Custom" -export type Publish = { is_finish: number; is_started: number; pub_time: string; pub_time_show: string; unknow_pub_date: number; weekday: number } +export type PublishInBangumi = { is_finish: number; is_started: number; pub_time: string; pub_time_show: string; unknow_pub_date: number; weekday: number } +export type PublishInBangumiFollow = { pub_time: string; pub_time_show: string; release_date: string; release_date_show: string; pub_time_show_db: string | null } export type PurchaseFormatNote = { content_list: ContentList[]; link: string; title: string } export type PurchaseNote = { content: string; link: string; title: string } export type PurchaseProtocol = { link: string; title: string } export type QrcodeData = { url: string; qrcode_key: string } export type QrcodeStatus = { url: string; refresh_token: string; timestamp: number; code: number; message: string } -export type Rating = { count: number; score: number } +export type RatingInBangumi = { count: number; score: number } +export type RatingInBangumiFollow = { score: number; count: number } export type RecommendSeason = { cover: string; ep_count: string; id: number; season_url: string; subtitle: string; title: string; view: number } export type Rights = { bp: number; elec: number; download: number; movie: number; pay: number; hd5: number; no_reprint: number; autoplay: number; ugc_pay: number; is_cooperation: number; ugc_pay_preview: number; no_background: number; clean_mode: number; is_stein_gate: number; is_360: number; no_share: number; arc_pay: number; free_watch: number } export type RightsInBangumi = { allow_bp: number; allow_bp_rank: number; allow_download: number; allow_review: number; area_limit: number; ban_area_show: number; can_watch: number; copyright: string; forbid_pre: number; freya_white: number; is_cover_show: number; is_preview: number; only_vip_download: number; resource: string; watch_platform: number } export type RightsInBangumiEp = { allow_dm: number; allow_download: number; area_limit: number } +export type RightsInBangumiFollow = { allow_review: number | null; allow_preview: number | null; is_selection: number; selection_style: number; is_rcmd: number | null; allow_bp_rank: number | null; allow_bp: number | null; allow_download: number | null } export type RightsInNormalEp = { bp: number; elec: number; download: number; movie: number; pay: number; hd5: number; no_reprint: number; autoplay: number; ugc_pay: number; is_cooperation: number; ugc_pay_preview: number; arc_pay: number; free_watch: number } export type RightsInWatchLater = { bp: number; elec: number; download: number; movie: number; pay: number; hd5: number; no_reprint: number; autoplay: number; ugc_pay: number; is_cooperation: number; ugc_pay_preview: number; no_background: number; arc_pay: number; pay_free_watch: number } export type SearchParams = { Normal: GetNormalInfoParams } | { Bangumi: GetBangumiInfoParams } | { Cheese: GetCheeseInfoParams } | { UserVideo: GetUserVideoInfoParams } | { Fav: GetFavInfoParams } export type SearchResult = { Normal: NormalSearchResult } | { Bangumi: BangumiSearchResult } | { Cheese: CheeseSearchResult } | { UserVideo: UserVideoSearchResult } | { Fav: FavSearchResult } -export type Season = { badge: string; badge_info: BadgeInfo; badge_type: number; cover: string; enable_vt: boolean; horizontal_cover_1610: string; horizontal_cover_169: string; icon_font: IconFont; media_id: number; new_ep: NewEpInSeason; season_id: number; season_title: string; season_type: number; stat: StatInSeason } +export type Season = { badge: string; badge_info: BadgeInfoInBangumi; badge_type: number; cover: string; enable_vt: boolean; horizontal_cover_1610: string; horizontal_cover_169: string; icon_font: IconFont; media_id: number; new_ep: NewEpInSeason; season_id: number; season_title: string; season_type: number; stat: StatInSeason } export type SectionInBangumi = { attr: number; episodes: EpInBangumi[]; id: number; title: string; type: number; type2: number } +export type SectionInBangumiFollow = { section_id: number; season_id: number; limit_group: number; watch_platform: number; copyright: string; ban_area_show: number; episode_ids: number[]; type: number | null; title: string | null; attr: number | null } export type SectionInNormal = { season_id: number; id: number; title: string; type: number; episodes: EpInNormal[] } -export type Series = { display_type: number; series_id: number; series_title: string } +export type SeriesInBangumi = { display_type: number; series_id: number; series_title: string } +export type SeriesInBangumiFollow = { series_id: number | null; title: string | null; season_count: number | null; new_season_id: number | null; series_ord: number | null } export type Show = { wide_screen: number } export type Skip = { ed: Ed; op: Op } export type Staff = { mid: number; title: string; name: string; face: string; follower: number; label_style: number } export type StatInBangumi = { coins: number; danmakus: number; favorite: number; favorites: number; follow_text: string; likes: number; reply: number; share: number; views: number; vt: number } +export type StatInBangumiFollow = { follow: number; view: number; danmaku: number; reply: number; coin: number; series_follow: number | null; series_view: number | null; likes: number; favorite: number } export type StatInCheese = { play: number; play_desc: string; show_vt: boolean } export type StatInNormal = { aid: number; view: number; danmaku: number; reply: number; favorite: number; coin: number; share: number; now_rank: number; his_rank: number; like: number; dislike: number; evaluation: string; vt: number } export type StatInNormalEp = { aid: number; view: number; danmaku: number; reply: number; fav: number; coin: number; share: number; now_rank: number; his_rank: number; like: number; dislike: number; evaluation: string; argue_msg: string; vt: number; vv: number } @@ -349,6 +378,7 @@ export type VideoQuality = "Unknown" | "240P" | "360P" | "480P" | "720P" | "720P export type VideoTask = { selected: boolean; url: string; video_quality: VideoQuality; codec_type: CodecType; content_length: number; chunks: MediaChunk[]; completed: boolean } export type VipInUserInfo = { type: number; status: number; due_date: number; vip_pay_type: number; theme_type: number; label: LabelInUserInfo; avatar_subscript: number; nickname_color: string; role: number; avatar_subscript_url: string; tv_vip_status: number; tv_vip_pay_type: number; tv_due_date: number } export type VipLabel = { path: string; text: string; label_theme: string; text_color: string; bg_style: number; bg_color: string; border_color: string; use_img_label: boolean; img_label_uri_hans: string; img_label_uri_hant: string; img_label_uri_hans_static: string; img_label_uri_hant_static: string } +export type VipOrPay = { text: string; bg_color: string; bg_color_night: string; img: string; multi_img: MultiImg } export type Wallet = { mid: number; bcoin_balance: number; coupon_balance: number; coupon_due_time: number } export type WatchLaterInfo = { count: number; list: MediaInWatchLater[] } export type WbiImg = { img_url: string; sub_url: string }