jx3_api/api/
free.rs

1use crate::Jx3ApiClient;
2use crate::enums::{CelebClub, ServerCheckEnums};
3use crate::err::Jx3ApiError;
4use crate::model::ApiResp;
5use crate::model::free::{
6    Announce, Answer, Calendar, Celeb, Flower, Furniture, ListCalendar, News, ServerMaster,
7    ServerStatus, SkillsRecord, Travel,
8};
9use serde_json::Value;
10use std::collections::HashMap;
11
12/// 活动日历
13const CALENDAR: &'static str = "/active/calendar";
14/// 活动月历
15const LIST_CALENDAR: &'static str = "/active/list/calendar";
16
17/// 行侠事件
18const CELEBS: &'static str = "/active/celebs";
19
20/// 科举答题
21const ANSWER: &'static str = "/exam/answer";
22
23///家园鲜花
24const FLOWER: &'static str = "/home/flower";
25
26///家园装饰
27const FURNITURE: &'static str = "/home/furniture";
28
29/// 器物图谱
30const TRAVEL: &'static str = "/home/travel";
31
32/// 新闻资讯
33const ALL_NEWS: &'static str = "/news/allnews";
34
35/// 维护公告
36const ANNOUNCE: &'static str = "/news/announce";
37
38/// 搜索区服
39const SERVER_MASTER: &'static str = "/server/master";
40
41/// 开服检查
42const SERVER_CHECK: &'static str = "/server/check";
43
44/// 查看状态
45const SERVER_STATUS: &'static str = "/server/status";
46
47/// 技改记录
48const SKILLS_RECORDS: &'static str = "/skills/records";
49
50impl Jx3ApiClient {
51    /// # 获取活动日历
52    /// 查询 今天、明天、后天 和 日常任务 的相关活动。
53    /// - 参数说明:
54    ///   - `server`:指定目标区服,获取该区服的美人图任务数据。
55    ///   - `num`: 指定日期的偏移值
56    ///     - 0:表示当天
57    ///     - 1:表示明天
58    ///     - 2:表示后天
59    ///     - 默认值为 0,即查询当天的数据。
60    ///
61    ///
62    /// - 返回示例:
63    /// ```json
64    ///   {
65    ///   "code": 200,
66    ///   "msg": "success",
67    ///   "data": {
68    ///     "date": "2024-12-08",
69    ///     "week": "日",
70    ///     "war": "大战!英雄冰川宫宝库",
71    ///     "battle": "神农洇",
72    ///     "orecar": "跨服·河西瀚漠",
73    ///     "school": "明教·血染红衣",
74    ///     "rescue": "少林·乱世",
75    ///     "luck": [
76    ///       "酒客",
77    ///       "圆圆",
78    ///       "鸿鸿"
79    ///     ],
80    ///     "card": [
81    ///       "英雄天子峰",
82    ///       "英雄日轮山城",
83    ///       "英雄风雨稻香村",
84    ///       "英雄剑冢"
85    ///     ],
86    ///     "team": [
87    ///       "洞天福地·守卫泥兰;龙泉府·雪国冬猎",
88    ///       "英雄雁门关之役;华清宫回忆录;英雄漳水南路",
89    ///       "一之窟;九老洞;河阳之战"
90    ///     ]
91    ///   },
92    ///   "time": 1733646979
93    /// }
94    /// ```
95    /// - 注:
96    ///   - 美人画图:仅在 星期三、星期五、星期六 和 星期日 有提供。若非活动时间,则不会返回相关数据。
97    ///   - 世界首领:仅在 星期三、星期五 存在,其他时间不返回。
98    pub async fn calendar(
99        &self,
100        server: Option<&str>,
101        num: Option<u8>,
102    ) -> Result<ApiResp<Calendar>, Jx3ApiError> {
103        let full_url = format!("{}{}", self.base_url, CALENDAR);
104        let mut body_map = HashMap::new();
105        if let Some(server) = server {
106            body_map.insert("server", Value::String(server.to_string()));
107        }
108        if let Some(num) = num {
109            body_map.insert("num", Value::Number(num.into()));
110        }
111
112        let resp = self
113            .client
114            .post(full_url)
115            .json(&body_map)
116            .send()
117            .await?
118            .json::<ApiResp<Calendar>>()
119            .await?;
120
121        match resp.code {
122            200 => Ok(resp),
123            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
124        }
125    }
126
127    /// # 活动月历
128    /// 该 API 用于预测每天的日常任务,您可以通过指定时间范围来获取相关任务数据。
129    /// - 参数说明:
130    ///   - `num`: 预测时间范围,返回指定日期的月历。默认值为 15,表示返回前后15天的日历数据。
131    /// - 返回示例:
132    /// ```json
133    /// {
134    ///   "code": 200,
135    ///   "msg": "success",
136    ///   "data": {
137    ///     "today": {
138    ///       "date": "2024-12-08",
139    ///       "week": "日",
140    ///       "year": "2024",
141    ///       "month": "12",
142    ///       "day": "08"
143    ///     },
144    ///     "data": [
145    ///       {
146    ///         "date": "2024-11-24",
147    ///         "day": "24",
148    ///         "week": "日",
149    ///         "war": "英雄不染窟",
150    ///         "battle": "浮香丘",
151    ///         "orecar": "跨服·河西瀚漠",
152    ///         "school": "唐门·对抗狼牙",
153    ///         "rescue": "七秀·乱世",
154    ///         "luck": [
155    ///           "鸿鸿",
156    ///           "将军客",
157    ///           "财财"
158    ///         ],
159    ///         "card": [
160    ///           "银雾湖",
161    ///           "狼牙堡·战兽山",
162    ///           "狼牙堡·燕然峰"
163    ///         ]
164    ///       }
165    ///     ]
166    ///   },
167    ///   "time": 1733654875
168    /// }
169    /// ```
170    ///
171
172    pub async fn list_calendar(
173        &self,
174        num: Option<u32>,
175    ) -> Result<ApiResp<ListCalendar>, Jx3ApiError> {
176        let full_url = format!("{}{}", self.base_url, LIST_CALENDAR);
177        let mut body_map = HashMap::new();
178        if let Some(num) = num {
179            body_map.insert("num", Value::Number(num.into()));
180        }
181        let resp = self
182            .client
183            .post(full_url)
184            .json(&body_map)
185            .send()
186            .await?
187            .json::<ApiResp<ListCalendar>>()
188            .await?;
189        match resp.code {
190            200 => Ok(resp),
191            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
192        }
193    }
194
195    /// # 行侠事件
196    /// 查询当前时间的楚天社或云从社的进度。
197    /// - 参数说明:
198    ///   - `name`:指定目标名称,返回指定事件的信息。可以选择 "楚天社" 或 "云从社" 以及 "披风会"。
199    /// - 返回示例:
200    /// ```json
201    /// {
202    ///   "code": 200,
203    ///   "msg": "success",
204    ///   "data": [
205    ///     {
206    ///        "map": "河西瀚漠",
207    ///        "stage": "并赃拿贼",
208    ///        "site": "北丘墓",
209    ///        "desc": "击退罗一空",
210    ///        "icon": "382",
211    ///        "time": "12:12"
212    ///      },
213    ///      {
214    ///        "map": "河西瀚漠",
215    ///        "stage": "淳朴民风",
216    ///        "site": "高昌城",
217    ///        "desc": "击败巴老九",
218    ///        "icon": "382",
219    ///        "time": "12:16"
220    ///     },
221    ///   ],
222    ///   "time": 1725570373
223    /// }
224    /// ```
225    pub async fn celebs(&self, name: CelebClub) -> Result<ApiResp<Vec<Celeb>>, Jx3ApiError> {
226        let full_url = format!("{}{}", self.base_url, CELEBS);
227        let mut body_map = HashMap::with_capacity(1);
228        body_map.insert("name", Value::String(name.to_str().to_string()));
229        let resp = self
230            .client
231            .post(full_url)
232            .json(&body_map)
233            .send()
234            .await?
235            .json::<ApiResp<Vec<Celeb>>>()
236            .await?;
237        match resp.code {
238            200 => Ok(resp),
239            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
240        }
241    }
242
243    /// # 科举答题
244    /// 此接口用于科举考试时的答案查询,支持模糊查询和拼音首字母查询。
245    /// - 参数说明:
246    ///   - `subject`:输入科举试题的题目内容,支持模糊查询或拼音首字母查询。例如输入 古琴 或 GQ。
247    ///   - `limit`:限制返回的答案数量,默认值为 10,取值范围为 1-20。
248    /// - 返回示例:
249    /// ```json
250    /// {
251    ///   "code": 200,
252    ///   "msg": "success",
253    ///   "data": [
254    ///     {
255    ///      "id": 885,
256    ///       "question": "单选题:古琴有几根弦?",
257    ///       "answer": "七根",
258    ///      "correctness": 1,
259    ///       "index": 2,
260    ///       "pinyin": "DXTGQYJGX"
261    ///     }
262    ///   ],
263    ///   "time": 1725571291
264    /// }
265    /// ```
266    ///
267    pub async fn answer(
268        &self,
269        subject: Option<&str>,
270        limit: Option<u8>,
271    ) -> Result<ApiResp<Vec<Answer>>, Jx3ApiError> {
272        let full_url = format!("{}{}", self.base_url, ANSWER);
273        let mut body_map = HashMap::new();
274        if let Some(subject) = subject {
275            body_map.insert("subject", Value::String(subject.to_string()));
276        }
277        if let Some(limit) = limit {
278            body_map.insert("limit", Value::Number(limit.into()));
279        }
280        let resp = self
281            .client
282            .post(full_url)
283            .json(&body_map)
284            .send()
285            .await?
286            .json::<ApiResp<Vec<Answer>>>()
287            .await?;
288        match resp.code {
289            200 => Ok(resp),
290            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
291        }
292    }
293
294    /// # 家园鲜花
295    /// 此接口用于查询家园系统中特定鲜花的最高价格及其对应的采集线路,包括区服和地图信息。
296    /// - 参数说明:
297    ///   - `server`:指定目标区服,查询目标区服的相关信息。
298    ///   - `name`: 指定鲜花名称,查询目标鲜花的相关信息。如果未指定,将返回所有鲜花的记录。
299    ///   - `map`: 指定目标地图,查询该地图的相关鲜花信息。如果未指定,将返回所有地图的记录。
300    /// - 返回参数说明:
301    ///   - `HashMap`的key为地图名称,value为该地图的鲜花列表。
302    /// - 返回示例:
303    /// ```json
304    /// {
305    ///   "code": 200,
306    ///   "msg": "success",
307    ///   "data": {
308    ///     "九寨沟·镜海": [
309    ///       {
310    ///         "name": "二级绣球花",
311    ///         "color": "金,蓝,粉",
312    ///        "price": 1.5,
313    ///         "line": [
314    ///          "11",
315    ///           "16",
316    ///          "10"
317    ///         ]
318    ///      }
319    ///     ]
320    ///   },
321    ///   "time": 1723007315
322    /// }
323    /// ```
324
325    pub async fn flower(
326        &self,
327        server: &str,
328        name: Option<&str>,
329        map: Option<&str>,
330    ) -> Result<ApiResp<HashMap<String, Vec<Flower>>>, Jx3ApiError> {
331        let full_url = format!("{}{}", self.base_url, FLOWER);
332        let mut body_map = HashMap::new();
333        body_map.insert("server", Value::String(server.to_string()));
334        if let Some(name) = name {
335            body_map.insert("name", Value::String(name.to_string()));
336        }
337        if let Some(map) = map {
338            body_map.insert("map", Value::String(map.to_string()));
339        }
340        let resp = self
341            .client
342            .post(full_url)
343            .json(&body_map)
344            .send()
345            .await?
346            .json::<ApiResp<HashMap<String, Vec<Flower>>>>()
347            .await?;
348        match resp.code {
349            200 => Ok(resp),
350            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
351        }
352    }
353
354    /// # 家园装饰
355    ///
356    /// 此接口用于查询家园系统中特定装饰的详细信息,包括来源、属性和外观等内容。
357    ///
358    /// - 参数说明:
359    ///   - `name`: 指定目标装饰的名称,查找该装饰的详细信息。
360    ///
361    /// - 返回示例:
362    /// ```json
363    /// {
364    ///   "code": 200,
365    ///   "msg": "success",
366    ///   "data": {
367    ///     "id": 1,
368    ///     "name": "龙门香梦",
369    ///     "type": 1,
370    ///     "color": 4,
371    ///     "source": "园宅会赛",
372    ///     "architecture": 0,
373    ///     "limit": 10,
374    ///     "quality": 1000,
375    ///     "view": 7931,
376    ///     "practical": 3525,
377    ///     "hard": 3525,
378    ///     "geomantic": 3525,
379    ///     "interesting": 3525,
380    ///     "produce": null,
381    ///     "image": "https://dl.pvp.xoyo.com/prod/icons/ui/image/homeland/data/source/home/furniture/cloth/cloth5_4_1001.mesh.png",
382    ///     "tip": "跳影如流泉,香梦过龙门。山中逍遥客,化为唤雨人。"
383    ///   },
384    ///  "time": 1723005805
385    /// }
386    ///
387    pub async fn furniture(&self, name: &str) -> Result<ApiResp<Vec<Furniture>>, Jx3ApiError> {
388        let full_url = format!("{}{}", self.base_url, FURNITURE);
389        let mut body_map = HashMap::new();
390        body_map.insert("name", Value::String(name.to_string()));
391        let resp = self
392            .client
393            .post(full_url)
394            .json(&body_map)
395            .send()
396            .await?
397            .json::<ApiResp<Vec<Furniture>>>()
398            .await?;
399        match resp.code {
400            200 => Ok(resp),
401            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
402        }
403    }
404
405    /// # 器物图谱
406    /// 此接口用于查询指定地图的装饰物品产出信息,包括装饰的属性、来源和外观等内容。
407    ///
408    /// - 参数说明:
409    ///   - `name`:指定目标地图的名称,查询该地图的装饰物品产出信息。
410    ///
411    /// - 返回示例:
412    ///
413    /// ```json
414    /// {
415    ///   "code": 200,
416    ///   "msg": "success",
417    ///   "data": [
418    ///     {
419    ///       "id": 422,
420    ///       "name": "日晷",
421    ///       "type": 1,
422    ///       "color": 3,
423    ///      "source": "宠物游历",
424    ///       "architecture": 0,
425    ///       "limit": 3,
426    ///       "quality": 615,
427    ///       "view": 484,
428    ///       "practical": 1743,
429    ///       "hard": 500,
430    ///       "geomantic": 500,
431    ///      "interesting": 0,
432    ///       "produce": "万花",
433    ///       "image": "https://dl.pvp.xoyo.com/prod/icons/ui/image/homeland/data/source/home/furniture/ornament/ornament1_1_1008_p.prefab.png",
434    ///       "tip": "产出地图:万花"
435    ///     }
436    ///   ],
437    ///   "time": 1723006304
438    /// }
439    ///
440    pub async fn travel(&self, name: &str) -> Result<ApiResp<Vec<Travel>>, Jx3ApiError> {
441        let full_url = format!("{}{}", self.base_url, TRAVEL);
442        let mut body_map = HashMap::new();
443        body_map.insert("name", Value::String(name.to_string()));
444        let resp = self
445            .client
446            .post(full_url)
447            .json(&body_map)
448            .send()
449            .await?
450            .json::<ApiResp<Vec<Travel>>>()
451            .await?;
452        match resp.code {
453            200 => Ok(resp),
454            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
455        }
456    }
457
458    /// # 新闻资讯
459    /// 此接口用于获取官方最新公告及新闻内容,包括新闻分类、标题及链接等信息。
460    ///
461    /// - 参数说明:
462    ///   - `limit`:  限制返回的新闻条数,默认值为 10,可选范围为 1-50。
463    ///
464    /// - 返回示例:
465    /// ```json
466    /// {
467    ///   "code": 200,
468    ///   "msg": "success",
469    ///   "data": [
470    ///     {
471    ///       "id": 2612,
472    ///       "token": 1334243,
473    ///       "class": "官方公告",
474    ///       "title": "12月9日例行维护公告",
475    ///       "date": "12/08",
476    ///       "url": "https://jx3.xoyo.com/announce/gg.html?id=1334243"
477    ///     }
478    ///   ],
479    ///   "time": 1733665940
480    /// }
481    /// ```
482    ///
483    pub async fn all_news(&self, limit: Option<u8>) -> Result<ApiResp<Vec<News>>, Jx3ApiError> {
484        let full_url = format!("{}{}", self.base_url, ALL_NEWS);
485        let mut body_map = HashMap::new();
486        if let Some(limit) = limit {
487            body_map.insert("limit", Value::Number(limit.into()));
488        }
489        let resp = self
490            .client
491            .post(full_url)
492            .json(&body_map)
493            .send()
494            .await?
495            .json::<ApiResp<Vec<News>>>()
496            .await?;
497        match resp.code {
498            200 => Ok(resp),
499            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
500        }
501    }
502
503    /// # 维护公告
504    /// 此接口用于获取官方最新维护公告,包括公告标题、发布日期及链接等信息。
505    /// - 参数说明:
506    ///   - `limit`:  限制返回的维护公告条数,默认值为 10,可选范围为 1-50。
507    /// - 返回示例:
508    /// ```json
509    /// {
510    ///   "code": 200,
511    ///   "msg": "success",
512    ///   "data": [
513    ///     {
514    ///       "id": 2607,
515    ///       "token": 1334235,
516    ///       "class": "官方公告",
517    ///       "title": "12月5日1.0.0.8799版本更新公告",
518    ///       "date": "12/05",
519    ///       "url": "https://jx3.xoyo.com/announce/gg.html?id=1334235"
520    ///     }
521    ///   ],
522    ///   "time": 1733666196
523    /// }
524    /// ```
525    pub async fn announce(&self, limit: Option<u8>) -> Result<ApiResp<Vec<Announce>>, Jx3ApiError> {
526        let full_url = format!("{}{}", self.base_url, ANNOUNCE);
527        let mut body_map = HashMap::new();
528        if let Some(limit) = limit {
529            body_map.insert("limit", Value::Number(limit.into()));
530        }
531        let resp = self
532            .client
533            .post(full_url)
534            .json(&body_map)
535            .send()
536            .await?
537            .json::<ApiResp<Vec<Announce>>>()
538            .await?;
539        match resp.code {
540            200 => Ok(resp),
541            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
542        }
543    }
544
545    /// # 搜索区服
546    /// 此接口用于根据区服简称搜索主服务器及其附属服务器的详细信息。
547    ///
548    /// - 参数说明:
549    ///   - `name`:指定目标区服的简称或名称,查询其主次服务器的详细信息。
550    ///
551    /// - 返回示例:
552    /// ```json
553    /// {
554    ///   "code": 200,
555    ///   "msg": "success",
556    ///   "data": {
557    ///     "id": "0502",
558    ///     "zone": "电信区",
559    ///     "name": "梦江南",
560    ///     "event": 36,
561    ///     "voice": {
562    ///       "浩气盟": [32968],
563    ///       "恶人谷": [36911]
564    ///     },
565    ///     "alias": [
566    ///       "双梦镇",
567    ///       "双梦"
568    ///     ],
569    ///     "slave": [
570    ///      "梦江南",
571    ///      "枫泾古镇",
572    ///       "如梦令"
573    ///     ]
574    ///   },
575    ///   "time": 1759917509
576    /// }
577    /// ```
578    pub async fn server_master(&self, name: &str) -> Result<ApiResp<ServerMaster>, Jx3ApiError> {
579        let full_url = format!("{}{}", self.base_url, SERVER_MASTER);
580        let mut body_map = HashMap::new();
581        body_map.insert("name", Value::String(name.to_string()));
582        let resp = self
583            .client
584            .post(full_url)
585            .json(&body_map)
586            .send()
587            .await?
588            .json::<ApiResp<ServerMaster>>()
589            .await?;
590        match resp.code {
591            200 => Ok(resp),
592            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
593        }
594    }
595
596    /// # 开服检查
597    /// 此接口用于查询指定服务器的当前状态,支持返回区服是否开服或维护中的信息。
598    /// - 参数说明:
599    ///   - `server`:指定目标服务名称,查询其当前状态。若未输入区服名称或输入错误的区服名称,将返回所有区服的状态数据,可用于开服监控(支持轮询请求)。
600    /// - 返回示例:
601    ///   - 示例1:
602    /// ```json
603    /// {
604    ///    "code": 200,
605    ///    "msg": "success",
606    ///    "data": {
607    ///      "id": 1,
608    ///      "zone": "电信区",
609    ///      "server": "长安城",
610    ///      "status": 1,
611    ///      "time": 1722977456
612    ///    },
613    ///    "time": 1723006935
614    ///  }
615    /// ```
616    ///   - 示例2:
617    /// ```json
618    /// {
619    ///   "code": 200,
620    ///   "msg": "success",
621    ///   "data": [
622    ///     {
623    ///       "id": 1,
624    ///       "zone": "电信区",
625    ///       "server": "长安城",
626    ///       "status": 1,
627    ///       "time": 1759709302
628    ///     },
629    ///     {
630    ///       "id": 2,
631    ///       "zone": "电信区",
632    ///       "server": "龙争虎斗",
633    ///       "status": 1,
634    ///       "time": 1759709302
635    ///     },
636    ///     {
637    ///       "id": 3,
638    ///       "zone": "电信区",
639    ///       "server": "蝶恋花",
640    ///       "status": 1,
641    ///       "time": 1759709301
642    ///     },
643    ///     {
644    ///       "id": 4,
645    ///       "zone": "电信区",
646    ///       "server": "剑胆琴心",
647    ///       "status": 1,
648    ///       "time": 1759709302
649    ///     },
650    ///     {
651    ///       "id": 5,
652    ///       "zone": "电信区",
653    ///       "server": "幽月轮",
654    ///       "status": 1,
655    ///       "time": 1759709302
656    ///     },
657    ///     {
658    ///       "id": 6,
659    ///       "zone": "电信区",
660    ///       "server": "乾坤一掷",
661    ///       "status": 1,
662    ///       "time": 1759709302
663    ///     },
664    ///     {
665    ///       "id": 7,
666    ///       "zone": "电信区",
667    ///       "server": "斗转星移",
668    ///       "status": 1,
669    ///       "time": 1759709302
670    ///     },
671    ///     {
672    ///       "id": 8,
673    ///       "zone": "电信区",
674    ///       "server": "唯我独尊",
675    ///       "status": 1,
676    ///       "time": 1759709302
677    ///     },
678    ///     {
679    ///       "id": 9,
680    ///       "zone": "电信区",
681    ///       "server": "梦江南",
682    ///       "status": 1,
683    ///       "time": 1759709302
684    ///     },
685    ///     {
686    ///       "id": 10,
687    ///       "zone": "电信区",
688    ///       "server": "绝代天骄",
689    ///       "status": 1,
690    ///       "time": 1759709302
691    ///     },
692    ///     {
693    ///       "id": 11,
694    ///       "zone": "双线区",
695    ///       "server": "破阵子",
696    ///       "status": 1,
697    ///       "time": 1759709302
698    ///     },
699    ///     {
700    ///       "id": 12,
701    ///       "zone": "双线区",
702    ///       "server": "天鹅坪",
703    ///       "status": 1,
704    ///       "time": 1759709302
705    ///     },
706    ///     {
707    ///       "id": 13,
708    ///       "zone": "双线区",
709    ///       "server": "飞龙在天",
710    ///       "status": 1,
711    ///       "time": 1759709302
712    ///     },
713    ///     {
714    ///       "id": 14,
715    ///       "zone": "双线区",
716    ///       "server": "青梅煮酒",
717    ///       "status": 0,
718    ///       "time": 1745447709
719    ///     },
720    ///     {
721    ///       "id": 15,
722    ///       "zone": "缘起区",
723    ///       "server": "缘起稻香",
724    ///       "status": 1,
725    ///       "time": 1759705416
726    ///     },
727    ///     {
728    ///       "id": 16,
729    ///       "zone": "缘起区",
730    ///       "server": "天宝盛世",
731    ///       "status": 1,
732    ///       "time": 1759705417
733    ///     },
734    ///     {
735    ///       "id": 17,
736    ///       "zone": "无界区",
737    ///       "server": "有人赴约",
738    ///       "status": 0,
739    ///       "time": 1745447709
740    ///     },
741    ///     {
742    ///       "id": 18,
743    ///       "zone": "无界区",
744    ///       "server": "山海相逢",
745    ///       "status": 1,
746    ///       "time": 1759709302
747    ///     },
748    ///     {
749    ///       "id": 20,
750    ///       "zone": "无界区",
751    ///       "server": "万象长安",
752    ///       "status": 0,
753    ///       "time": 1745447709
754    ///     },
755    ///     {
756    ///       "id": 21,
757    ///       "zone": "无界区",
758    ///       "server": "眉间雪",
759    ///       "status": 1,
760    ///       "time": 1759709302
761    ///     }
762    ///   ],
763    ///   "time": 1759918555
764    /// }
765    /// ```
766
767    pub async fn server_check(
768        &self,
769        server: Option<&str>,
770    ) -> Result<ApiResp<ServerCheckEnums>, Jx3ApiError> {
771        let full_url = format!("{}{}", self.base_url, SERVER_CHECK);
772        let mut body_map = HashMap::new();
773        if let Some(server) = server {
774            body_map.insert("server", Value::String(server.to_string()));
775        }
776        let resp = self
777            .client
778            .post(full_url)
779            .json(&body_map)
780            .send()
781            .await?
782            .json::<ApiResp<ServerCheckEnums>>()
783            .await?;
784        match resp.code {
785            200 => Ok(resp),
786            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
787        }
788    }
789
790    /// # 查看状态
791    /// 此接口用于查询指定服务器的当前状态,包括 维护、正常、繁忙 和 爆满 等状态信息。
792    /// - 参数说明:
793    ///   - `server`: 指定目标区服的名称,查询该区服的状态信息。
794    /// - 返回示例:
795    /// ```json
796    /// {
797    ///   "code": 200,
798    ///   "msg": "success",
799    ///   "data": {
800    ///     "zone": "电信区",
801    ///     "server": "长安城",
802    ///     "status": "爆满"
803    ///   },
804    ///   "time": 1723007064
805    /// }
806    /// ```
807    pub async fn server_status(&self, server: &str) -> Result<ApiResp<ServerStatus>, Jx3ApiError> {
808        let full_url = format!("{}{}", self.base_url, SERVER_STATUS);
809        let mut body_map = HashMap::new();
810        body_map.insert("server", Value::String(server.to_string()));
811        let resp = self
812            .client
813            .post(full_url)
814            .json(&body_map)
815            .send()
816            .await?
817            .json::<ApiResp<ServerStatus>>()
818            .await?;
819        match resp.code {
820            200 => Ok(resp),
821            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
822        }
823    }
824
825    /// # 技改记录
826    /// 此接口用于查询技能的历史修改记录,包括资料片更新、技能调整等信息。
827    /// - 返回示例:
828    /// ```json
829    /// {
830    ///   "code": 200,
831    ///   "msg": "success",
832    ///   "data": [
833    ///     {
834    ///      "id": "1334209",
835    ///      "title": "11月21日“丝路风语”资料片武学调整",
836    ///      "url": "https://jx3.xoyo.com/announce/gg.html?id=1334209",
837    ///      "time": "2024-11-20 23:06:15"
838    ///    }
839    ///   ],
840    ///  "time": 1733668273
841    /// }
842    /// ```
843    pub async fn skills_records(&self) -> Result<ApiResp<Vec<SkillsRecord>>, Jx3ApiError> {
844        let full_url = format!("{}{}", self.base_url, SKILLS_RECORDS);
845        let resp = self
846            .client
847            .get(full_url)
848            .send()
849            .await?
850            .json::<ApiResp<Vec<SkillsRecord>>>()
851            .await?;
852        match resp.code {
853            200 => Ok(resp),
854            _ => Err(Jx3ApiError::ApiError(resp.code, resp.msg)),
855        }
856    }
857}
858
859#[cfg(test)]
860mod examples {
861    use super::*;
862
863    #[tokio::test]
864    async fn test_calendar_example() -> Result<(), Jx3ApiError> {
865        let client = Jx3ApiClient::new();
866        let resp = client.calendar(Some("长安城"), Some(1)).await?;
867        println!("{:?}", resp);
868        Ok(())
869    }
870
871    #[tokio::test]
872    async fn test_list_calendar_example() -> Result<(), Jx3ApiError> {
873        let client = Jx3ApiClient::new();
874        let resp = client.list_calendar(Some(7)).await?;
875        println!("{:?}", resp);
876        Ok(())
877    }
878
879    #[tokio::test]
880    async fn test_celebs_example() -> Result<(), Jx3ApiError> {
881        let client = Jx3ApiClient::new();
882        let resp = client.celebs(CelebClub::Cts).await?;
883        println!("{:?}", resp);
884        Ok(())
885    }
886
887    #[tokio::test]
888    async fn test_answer_example() -> Result<(), Jx3ApiError> {
889        let client = Jx3ApiClient::new();
890        let resp = client.answer(Some("古琴"), Some(10)).await?;
891        println!("{:?}", resp);
892        Ok(())
893    }
894
895    #[tokio::test]
896    async fn test_flower_example() -> Result<(), Jx3ApiError> {
897        let client = Jx3ApiClient::new();
898        let resp = client
899            .flower("梦江南", Some("绣球花"), Some("九寨沟·镜海"))
900            .await?;
901        println!("{:?}", resp);
902        Ok(())
903    }
904
905    #[tokio::test]
906    async fn test_furniture_example() -> Result<(), Jx3ApiError> {
907        let client = Jx3ApiClient::new();
908        let resp = client.furniture("龙门香梦").await?;
909        println!("{:?}", resp);
910        Ok(())
911    }
912
913    #[tokio::test]
914    async fn test_travel_example() -> Result<(), Jx3ApiError> {
915        let client = Jx3ApiClient::new();
916        let resp = client.travel("万花").await?;
917        println!("{:?}", resp);
918        Ok(())
919    }
920
921    #[tokio::test]
922    async fn test_all_news_example() -> Result<(), Jx3ApiError> {
923        let client = Jx3ApiClient::new();
924        let resp = client.all_news(Some(1)).await?;
925        println!("{:?}", resp);
926        Ok(())
927    }
928
929    #[tokio::test]
930    async fn test_announce_example() -> Result<(), Jx3ApiError> {
931        let client = Jx3ApiClient::new();
932        let resp = client.announce(Some(1)).await?;
933        println!("{:?}", resp);
934        Ok(())
935    }
936
937    #[tokio::test]
938    async fn test_master_example() -> Result<(), Jx3ApiError> {
939        let client = Jx3ApiClient::new();
940        let resp = client.server_master("双梦镇").await?;
941        println!("{:?}", resp);
942        Ok(())
943    }
944
945    #[tokio::test]
946    async fn test_server_check_example() -> Result<(), Jx3ApiError> {
947        let client = Jx3ApiClient::new();
948        let resp = client.server_check(Some("长安城")).await?;
949        println!("{:?}", resp);
950        let resp = client.server_check(None).await?;
951        println!("{:?}", resp);
952        Ok(())
953    }
954
955    #[tokio::test]
956    async fn test_server_status_example() -> Result<(), Jx3ApiError> {
957        let client = Jx3ApiClient::new();
958        let resp = client.server_status("长安城").await?;
959        println!("{:?}", resp);
960        Ok(())
961    }
962
963    #[tokio::test]
964    async fn test_skills_records_example() -> Result<(), Jx3ApiError> {
965        let client = Jx3ApiClient::new();
966        let resp = client.skills_records().await?;
967        println!("{:?}", resp);
968        Ok(())
969    }
970}