bangumi_api/module/collection/
service.rs

1use anyhow::Result;
2use reqwest::Method;
3
4use crate::{
5    common::model::BangumiClient,
6    module::{episode::model::EpisodeType, model::Paged, subject::model::SubjectType},
7};
8
9use super::model::{
10    CollectionCharacter, CollectionEpisode, CollectionEpisodeUpdate, CollectionEpisodesUpdate,
11    CollectionPerson, CollectionSubject, CollectionSubjectUpdate, CollectionType,
12};
13
14impl BangumiClient {
15    /// 获取用户的收藏条目列表
16    ///
17    /// 支持按条目类型、收藏状态筛选,并提供分页功能
18    ///
19    /// # 参数
20    /// - `username`: 用户名(目标用户的名称)
21    /// - `subject_type`: 可选,按条目类型筛选(如动画、书籍等)
22    /// - `r#type`: 可选,按收藏状态筛选(如想看、在看等)
23    /// - `limit`: 可选,每页返回结果数量
24    /// - `offset`: 可选,结果偏移量(用于分页)
25    ///
26    /// # 返回
27    /// 返回包含收藏条目的分页结果
28    pub async fn get_collection_subjects(
29        &self,
30        username: &str,
31        subject_type: Option<SubjectType>,
32        r#type: Option<CollectionType>,
33        limit: Option<u32>,
34        offset: Option<u32>,
35    ) -> Result<Paged<CollectionSubject>> {
36        // 构建请求URL:用户收藏条目列表接口
37        let url = format!("{}/v0/users/{username}/collections", self.base_path);
38
39        let mut request_builder = self.request_builder(Method::GET, &url);
40
41        // 添加条目类型筛选参数
42        if let Some(ref param_value) = subject_type {
43            request_builder = request_builder.query(&[("subject_type", &param_value)]);
44        }
45        // 添加收藏状态筛选参数
46        if let Some(ref param_value) = r#type {
47            request_builder = request_builder.query(&[("type", &param_value)]);
48        }
49        // 添加分页参数:每页数量
50        if let Some(ref param_value) = limit {
51            request_builder = request_builder.query(&[("limit", &param_value)]);
52        }
53        // 添加分页参数:偏移量
54        if let Some(ref param_value) = offset {
55            request_builder = request_builder.query(&[("offset", &param_value)]);
56        }
57
58        // 发送请求并解析分页结果
59        let res = self.request_send(request_builder).await?.json().await?;
60
61        Ok(res)
62    }
63
64    /// 获取用户对特定条目的收藏详情
65    ///
66    /// 查询指定用户对某个条目的收藏状态、评分、评论等信息
67    ///
68    /// # 参数
69    /// - `username`: 用户名
70    /// - `subject_id`: 条目ID
71    ///
72    /// # 返回
73    /// 返回该条目对应的收藏详情
74    pub async fn get_collection_subject(
75        &self,
76        username: &str,
77        subject_id: u32,
78    ) -> Result<CollectionSubject> {
79        // 构建请求URL:用户特定条目收藏详情接口
80        let url = format!(
81            "{}/v0/users/{username}/collections/{subject_id}",
82            self.base_path
83        );
84
85        let request_builder = self.request_builder(Method::GET, &url);
86
87        // 发送请求并解析收藏详情
88        let res = self.request_send(request_builder).await?.json().await?;
89
90        Ok(res)
91    }
92
93    /// 创建或更新当前用户对条目的收藏
94    ///
95    /// 用于提交或修改用户对指定条目的收藏状态(需认证)
96    ///
97    /// # 参数
98    /// - `subject_id`: 条目ID
99    /// - `payload`: 收藏更新参数(包含状态、评分、进度等)
100    ///
101    /// # 返回
102    /// 操作成功返回空结果,失败返回错误
103    pub async fn post_collection_subject(
104        &self,
105        subject_id: u32,
106        payload: Option<CollectionSubjectUpdate>,
107    ) -> Result<()> {
108        // 构建请求URL:当前用户条目收藏操作接口("-"表示当前认证用户)
109        let url = format!("{}/v0/users/-/collections/{subject_id}", self.base_path);
110
111        let mut request_builder = self.request_builder(Method::POST, &url);
112        // 添加请求体参数
113        request_builder = request_builder.json(&payload);
114
115        // 发送请求并忽略响应内容
116        let _res = self.request_send(request_builder).await?;
117
118        Ok(())
119    }
120
121    /// 部分更新当前用户对条目的收藏
122    ///
123    /// 用于增量修改收藏信息(如仅更新评分或进度,需认证)
124    ///
125    /// # 参数
126    /// - `subject_id`: 条目ID
127    /// - `payload`: 部分更新参数(可选字段,仅修改指定内容)
128    ///
129    /// # 返回
130    /// 操作成功返回空结果,失败返回错误
131    pub async fn patch_collection_subject(
132        &self,
133        subject_id: u32,
134        payload: Option<CollectionSubjectUpdate>,
135    ) -> Result<()> {
136        // 构建请求URL:当前用户条目收藏部分更新接口
137        let url = format!("{}/v0/users/-/collections/{subject_id}", self.base_path);
138
139        let mut request_builder = self.request_builder(Method::PATCH, &url);
140        // 添加请求体参数
141        request_builder = request_builder.json(&payload);
142
143        // 发送请求并忽略响应内容
144        let _res = self.request_send(request_builder).await?;
145
146        Ok(())
147    }
148
149    /// 获取当前用户条目的剧集收藏状态
150    ///
151    /// 查询指定条目下各剧集的收藏/观看状态(需认证)
152    ///
153    /// # 参数
154    /// - `subject_id`: 条目ID
155    /// - `offset`: 可选,结果偏移量(分页用)
156    /// - `limit`: 可选,每页数量
157    /// - `episode_type`: 可选,按剧集类型筛选(如正片、SP等)
158    ///
159    /// # 返回
160    /// 返回包含剧集收藏状态的分页结果
161    pub async fn get_collection_episodes(
162        &self,
163        subject_id: u32,
164        offset: Option<u32>,
165        limit: Option<u32>,
166        episode_type: Option<EpisodeType>,
167    ) -> Result<Paged<CollectionEpisode>> {
168        // 构建请求URL:当前用户条目剧集收藏接口
169        let url = format!(
170            "{}/v0/users/-/collections/{subject_id}/episodes",
171            self.base_path
172        );
173
174        let mut request_builder = self.request_builder(Method::GET, &url);
175
176        // 添加分页参数
177        if let Some(ref param_value) = offset {
178            request_builder = request_builder.query(&[("offset", &param_value)]);
179        }
180        if let Some(ref param_value) = limit {
181            request_builder = request_builder.query(&[("limit", &param_value)]);
182        }
183        // 添加剧集类型筛选参数
184        if let Some(ref param_value) = episode_type {
185            request_builder = request_builder.query(&[("episode_type", &param_value)]);
186        }
187
188        // 发送请求并解析分页结果
189        let res = self.request_send(request_builder).await?.json().await?;
190
191        Ok(res)
192    }
193
194    /// 批量更新当前用户剧集收藏状态
195    ///
196    /// 用于一次性修改多个剧集的收藏状态(需认证)
197    ///
198    /// # 参数
199    /// - `subject_id`: 条目ID
200    /// - `payload`: 批量更新参数(包含剧集ID列表和目标状态)
201    ///
202    /// # 返回
203    /// 操作成功返回空结果,失败返回错误
204    pub async fn patch_collection_episodes(
205        &self,
206        subject_id: u32,
207        payload: Option<CollectionEpisodesUpdate>,
208    ) -> Result<()> {
209        // 构建请求URL:当前用户剧集批量收藏更新接口
210        let url = format!(
211            "{}/v0/users/-/collections/{subject_id}/episodes",
212            self.base_path
213        );
214
215        let mut request_builder = self.request_builder(Method::PATCH, &url);
216        // 添加请求体参数
217        request_builder = request_builder.json(&payload);
218
219        // 发送请求并忽略响应内容
220        let _res = self.request_send(request_builder).await?;
221
222        Ok(())
223    }
224
225    /// 获取当前用户单个剧集的收藏状态
226    ///
227    /// 查询指定剧集的收藏/观看状态(需认证)
228    ///
229    /// # 参数
230    /// - `episode_id`: 剧集ID
231    ///
232    /// # 返回
233    /// 返回该剧集的收藏状态详情
234    pub async fn get_collection_episode(&self, episode_id: u32) -> Result<CollectionEpisode> {
235        // 构建请求URL:当前用户单个剧集收藏状态接口
236        let url = format!(
237            "{}/v0/users/-/collections/-/episodes/{episode_id}",
238            self.base_path
239        );
240
241        let request_builder = self.request_builder(Method::GET, &url);
242
243        // 发送请求并解析结果
244        let res = self.request_send(request_builder).await?.json().await?;
245
246        Ok(res)
247    }
248
249    /// 更新当前用户单个剧集的收藏状态
250    ///
251    /// 修改指定剧集的收藏/观看状态(需认证)
252    ///
253    /// # 参数
254    /// - `episode_id`: 剧集ID
255    /// - `payload`: 剧集状态更新参数
256    ///
257    /// # 返回
258    /// 返回 Ok(())
259    pub async fn put_collection_episode(
260        &self,
261        episode_id: u32,
262        payload: Option<CollectionEpisodeUpdate>,
263    ) -> Result<()> {
264        // 构建请求URL:当前用户单个剧集收藏更新接口
265        let url = format!(
266            "{}/v0/users/-/collections/-/episodes/{episode_id}",
267            self.base_path
268        );
269
270        let mut request_builder = self.request_builder(Method::PUT, &url);
271        // 添加请求体参数
272        request_builder = request_builder.json(&payload);
273
274        // 发送请求并解析更新后的结果
275        let _res = self.request_send(request_builder).await?;
276
277        Ok(())
278    }
279
280    /// 获取用户收藏的角色列表
281    ///
282    /// 查询指定用户收藏的所有角色(支持分页)
283    ///
284    /// # 参数
285    /// - `username`: 用户名
286    ///
287    /// # 返回
288    /// 返回包含收藏角色的分页结果
289    pub async fn get_collection_characters(
290        &self,
291        username: &str,
292    ) -> Result<Paged<CollectionCharacter>> {
293        // 构建请求URL:用户角色收藏列表接口
294        let url = format!(
295            "{}/v0/users/{username}/collections/-/characters",
296            self.base_path
297        );
298
299        let request_builder = self.request_builder(Method::GET, &url);
300
301        // 发送请求并解析分页结果
302        let res = self.request_send(request_builder).await?.json().await?;
303
304        Ok(res)
305    }
306
307    /// 获取用户对特定角色的收藏详情
308    ///
309    /// 查询指定用户对某个角色的收藏信息
310    ///
311    /// # 参数
312    /// - `username`: 用户名
313    /// - `character_id`: 角色ID
314    ///
315    /// # 返回
316    /// 返回该角色的收藏详情
317    pub async fn get_collection_character(
318        &self,
319        username: &str,
320        character_id: u32,
321    ) -> Result<CollectionCharacter> {
322        // 构建请求URL:用户特定角色收藏详情接口
323        let url = format!(
324            "{}/v0/users/{username}/collections/-/characters/{character_id}",
325            self.base_path
326        );
327
328        let request_builder = self.request_builder(Method::GET, &url);
329
330        // 发送请求并解析结果
331        let res = self.request_send(request_builder).await?.json().await?;
332
333        Ok(res)
334    }
335
336    /// 获取用户收藏的人物列表
337    ///
338    /// 查询指定用户收藏的所有人物(如配音演员、导演等,支持分页)
339    ///
340    /// # 参数
341    /// - `username`: 用户名
342    ///
343    /// # 返回
344    /// 返回包含收藏人物的分页结果
345    pub async fn get_collection_persons(&self, username: &str) -> Result<Paged<CollectionPerson>> {
346        // 构建请求URL:用户人物收藏列表接口
347        let url = format!(
348            "{}/v0/users/{username}/collections/-/persons",
349            self.base_path
350        );
351
352        let request_builder = self.request_builder(Method::GET, &url);
353
354        // 发送请求并解析分页结果
355        let res = self.request_send(request_builder).await?.json().await?;
356
357        Ok(res)
358    }
359
360    /// 获取用户对特定人物的收藏详情
361    ///
362    /// 查询指定用户对某个人物的收藏信息
363    ///
364    /// # 参数
365    /// - `username`: 用户名
366    /// - `person_id`: 人物ID
367    ///
368    /// # 返回
369    /// 返回该人物的收藏详情
370    pub async fn get_collection_person(
371        &self,
372        username: &str,
373        person_id: u32,
374    ) -> Result<CollectionPerson> {
375        // 构建请求URL:用户特定人物收藏详情接口
376        let url = format!(
377            "{}/v0/users/{username}/collections/-/persons/{person_id}",
378            self.base_path
379        );
380
381        let request_builder = self.request_builder(Method::GET, &url);
382
383        // 发送请求并解析结果
384        let res = self.request_send(request_builder).await?.json().await?;
385
386        Ok(res)
387    }
388}