Skip to main content

bpi_rs/creativecenter/season/
edit.rs

1// 编辑合集小节 API
2//
3// [参考文档](https://github.com/Yuelioi/bilibili-API-collect/tree/cfc5fddcc8a94b74d91970bb5b4eaeb349addc47/docs/creativecenter/season.md)
4
5use crate::BilibiliRequest;
6use crate::BpiResult;
7use crate::creativecenter::CreativeCenterClient;
8use serde::{Deserialize, Serialize};
9use serde_json::json;
10
11/// 合集信息编辑
12
13#[derive(Debug, Clone, Serialize, Deserialize, Default)]
14pub struct SeasonEdit {
15    pub id: u64,       // 合集 ID
16    pub title: String, // 合集标题
17    pub cover: String, // 封面图 URL
18    #[serde(default)]
19    pub desc: Option<String>, // 合集简介
20    #[serde(default)]
21    pub season_price: Option<u32>, // 合集价格(默认 0)
22    #[serde(default, rename = "isEnd")]
23    pub is_end: Option<u32>, // 是否完结 0:未完结 1:完结
24}
25
26/// 合集小节信息
27#[derive(Debug, Clone, Default, Serialize, Deserialize)]
28pub struct SeasonSectionEdit {
29    pub id: u64,
30    #[serde(rename = "type")]
31    pub type_field: u64,
32    #[serde(rename = "seasonId")]
33    pub season_id: u64,
34    pub title: String,
35}
36
37/// 合集内视频排序信息
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct SectionSort {
40    pub id: u64,    // 合集内视频 ID
41    pub order: u32, // 排序位置
42}
43
44#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
45pub struct EpisodeEdit {
46    pub id: u64,
47    pub title: String,
48    pub aid: u64,
49    pub cid: u64,
50    #[serde(rename = "seasonId")]
51    pub season_id: u64,
52    #[serde(rename = "sectionId")]
53    pub section_id: u64,
54    pub sorts: Vec<EpisodeSort>,
55    pub order: u64,
56}
57
58#[derive(Serialize)]
59struct EpisodeEditPayload {
60    #[serde(flatten)]
61    section: EpisodeEdit,
62    sorts: Vec<EpisodeSort>,
63}
64
65#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
66pub struct EpisodeSort {
67    pub id: u64,
68    pub sort: u64,
69}
70
71/// 合集小节排序信息
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct SeasonSectionSort {
74    pub id: u64,   // 小节 ID
75    pub sort: u32, // 排序位置
76}
77
78#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
79pub struct SectionAddEpisodesRequest {
80    #[serde(rename = "sectionId")]
81    pub section_id: u64,
82    pub episodes: Vec<Episode>,
83}
84
85#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
86pub struct Episode {
87    pub title: String,
88    pub aid: u64,
89    pub cid: u64,
90    pub charging_pay: i64,
91    pub member_first: i64,
92    pub limited_free: bool,
93}
94
95impl<'a> CreativeCenterClient<'a> {
96    /// 编辑合集信息
97    ///
98    /// 编辑合集的基本信息,包括标题、封面、简介等。
99    ///
100    /// # 参数
101    /// | 名称 | 类型 | 说明 |
102    /// | ---- | ---- | ---- |
103    /// | `season` | SeasonEdit | 合集信息 |
104    /// | `sorts` | `Vec<SeasonSectionSort>` | 小节排序列表 |
105    ///
106    /// # 文档
107    /// [编辑合集信息](https://github.com/Yuelioi/bilibili-API-collect/tree/cfc5fddcc8a94b74d91970bb5b4eaeb349addc47/docs/creativecenter/season/edit.md#编辑合集信息)
108    pub async fn season_edit(
109        &self,
110        season: SeasonEdit,
111        sorts: Vec<SeasonSectionSort>,
112    ) -> BpiResult<Option<serde_json::Value>> {
113        let csrf = self.client.csrf()?;
114
115        let payload = json!({
116            "season": season,
117            "sorts": sorts
118        });
119
120        self.client
121            .post("https://member.bilibili.com/x2/creative/web/season/edit")
122            .query(&[("csrf", csrf)])
123            .json(&payload)
124            .send_bpi_optional_payload("creativecenter.season.edit")
125            .await
126    }
127    /// 编辑合集小节(需要开启小节功能)
128    ///
129    /// 编辑合集中的小节信息,包括小节标题和视频排序。
130    ///
131    /// # 参数
132    /// | 名称 | 类型 | 说明 |
133    /// | ---- | ---- | ---- |
134    /// | `section` | SeasonSectionEdit | 小节信息 |
135    /// | `sorts` | `Vec<SectionSort>` | 视频排序信息 |
136    ///
137    /// # 文档
138    /// [编辑合集小节](https://github.com/Yuelioi/bilibili-API-collect/tree/cfc5fddcc8a94b74d91970bb5b4eaeb349addc47/docs/creativecenter/season/edit.md#编辑合集小节)
139    pub async fn season_section_edit(
140        &self,
141        section: SeasonSectionEdit,
142        sorts: Vec<SectionSort>,
143    ) -> BpiResult<Option<serde_json::Value>> {
144        let csrf = self.client.csrf()?;
145
146        let payload = json!({
147            "section": section,
148            "sorts": sorts
149        });
150
151        self.client
152            .post("https://member.bilibili.com/x2/creative/web/season/section/edit")
153            .query(&[("csrf", csrf)])
154            .json(&payload)
155            .send_bpi_optional_payload("creativecenter.season.section.edit")
156            .await
157    }
158
159    /// 编辑小节中的章节
160    ///
161    /// 编辑合集中的小节信息,包括小节标题和视频排序。
162    ///
163    /// # 参数
164    /// | 名称 | 类型 | 说明 |
165    /// | ---- | ---- | ---- |
166    /// | `section` | SeasonSectionEdit | 小节信息 |
167    /// | `sorts` | `Vec<SectionSort>` | 视频排序信息 |
168    ///
169    /// # 文档
170    /// [编辑合集小节](https://github.com/Yuelioi/bilibili-API-collect/tree/cfc5fddcc8a94b74d91970bb5b4eaeb349addc47/docs/creativecenter/season/edit.md#编辑合集小节)
171    pub async fn season_section_episode_edit(
172        &self,
173        section: EpisodeEdit,
174        sorts: Vec<EpisodeSort>,
175    ) -> BpiResult<Option<serde_json::Value>> {
176        let csrf = self.client.csrf()?;
177
178        let payload = EpisodeEditPayload { section, sorts };
179
180        self.client
181            .post("https://member.bilibili.com/x2/creative/web/season/section/episode/edit")
182            .query(&[("csrf", csrf)])
183            .json(&payload)
184            .send_bpi_optional_payload("creativecenter.season.section.episode.edit")
185            .await
186    }
187
188    /// 切换小节/正常显示
189    ///
190    /// # 参数
191    /// * season_id 合集id
192    pub async fn season_enable_section(
193        &self,
194        season_id: u64,
195        enable: bool,
196    ) -> BpiResult<Option<serde_json::Value>> {
197        let csrf = self.client.csrf()?;
198        let params = vec![
199            ("csrf", csrf),
200            ("season_id", season_id.to_string()),
201            ("no_section", (if enable { "0" } else { "1" }).to_string()),
202        ];
203
204        self.client
205            .post("https://member.bilibili.com/x2/creative/web/season/section/switch")
206            .form(&params)
207            .send_bpi_optional_payload("creativecenter.season.section.switch")
208            .await
209    }
210    /// 添加视频到小节(需要开启小节功能)
211    ///
212    /// 将视频添加到指定的合集小节中。
213    ///
214    /// # 参数
215    /// | 名称 | 类型 | 说明 |
216    /// | ---- | ---- | ---- |
217    /// | `aid` | u64 | 视频 aid |
218    /// | `season_id` | u64 | 合集 ID |
219    /// | `section_id` | u64 | 小节 ID |
220    /// | `title` | &str | 视频标题 |
221    ///
222    /// # 文档
223    /// [编辑投稿视频合集/小节](https://github.com/Yuelioi/bilibili-API-collect/tree/cfc5fddcc8a94b74d91970bb5b4eaeb349addc47/docs/creativecenter/season/edit.md#编辑投稿视频合集小节)
224    pub async fn season_section_add_episodes(
225        &self,
226        section_id: u64,
227        episodes: Vec<Episode>,
228    ) -> BpiResult<Option<serde_json::Value>> {
229        let csrf = self.client.csrf()?;
230
231        let payload = SectionAddEpisodesRequest {
232            section_id,
233            episodes,
234        };
235
236        self.client
237            .post("https://member.bilibili.com/x2/creative/web/season/section/episodes/add")
238            .json(&payload)
239            .query(&[("csrf", csrf)])
240            .send_bpi_optional_payload("creativecenter.season.section.episodes.add")
241            .await
242    }
243}
244
245#[cfg(test)]
246mod tests {}