1use serde::{Deserialize, Serialize};
2
3use crate::{
4 Client,
5 course::{Course, Jxb},
6 error::{Error, R},
7 utils::macros::{debug, info, trace, warn},
8};
9
10impl Client {
11 pub async fn fetch_courses(&self, q: &str) -> R<Course> {
13 info!("查询课程,q: {}", q);
14
15 #[derive(Serialize, Debug)]
16 struct PartDisplayRequestData<'a> {
17 #[serde(rename = "filter_list[0]")]
18 filter_list: &'a str,
19 xbm: &'a str,
20 ccdm: &'a str,
21 kklxdm: &'a str,
22 xkxnm: &'a str, xkxqm: &'a str, jg_id: &'a str, xsbj: &'a str, mzm: &'a str,
27 xz: &'a str, bh_id: &'a str, xqh_id: &'a str, zyfx_id: &'a str, xslbdm: &'a str,
32 kspage: &'a str,
33 jspage: &'a str,
34 }
35
36 let part_display_data = PartDisplayRequestData {
37 filter_list: q.into(),
38 xbm: self.use_store("xbm"),
39 ccdm: self.use_store("ccdm"),
40 kklxdm: self.use_store("firstKklxdm"),
41 xkxnm: self.use_store("xkxnm"),
42 xkxqm: self.use_store("xkxqm"),
43 jg_id: self.use_store("jg_id_1"),
44 xsbj: self.use_store("xsbj"),
45 mzm: self.use_store("mzm"),
46 xz: self.use_store("xz"),
47 bh_id: self.use_store("bh_id"),
48 xqh_id: self.use_store("xqh_id"),
49 zyfx_id: self.use_store("zyfx_id"),
50 xslbdm: self.use_store("xslbdm"),
51 kspage: "1",
52 jspage: "10",
53 };
54
55 #[derive(Deserialize, Debug)]
56 struct PartDisplayResponseData {
57 #[serde(rename = "tmpList")]
58 tmp_list: Vec<PartDisplayResponseInnerData>,
59 }
60
61 impl PartDisplayResponseData {
62 fn use_first_kch_id(&self) -> R<&String> {
63 Ok(&self
64 .tmp_list
65 .get(0)
66 .ok_or(Error::JxbNotFound("~.tmp_list.0"))?
67 .kch_id)
68 }
69 }
70
71 #[derive(Deserialize, Debug)]
72 struct PartDisplayResponseInnerData {
73 kch_id: String, }
78
79 trace!("part_display request");
80
81 let part_display_res = self
82 .post(&Client::SELECT_COURSE_PART_DISPLAY_URL)
83 .form(&part_display_data)
84 .send()
85 .await?
86 .json::<PartDisplayResponseData>()
87 .await?;
88
89 debug!("part_display {:#?}", part_display_res);
90
91 #[derive(Serialize, Debug)]
92 struct QueryDoWithCouresIdRequestData<'a> {
93 #[serde(rename = "filter_list[0]")]
94 filter_list: &'a str,
95 xkxqm: &'a str,
96 xkxnm: &'a str,
97 xkkz_id: &'a str,
98 bklx_id: &'a str,
99 kch_id: &'a str, njdm_id: &'a str, xsbj: &'a str,
102 xz: &'a str, mzm: &'a str,
104 kklxdm: &'a str,
105 bh_id: &'a str,
106 xqh_id: &'a str,
107 xslbdm: &'a str,
108 zyfx_id: &'a str,
109 jg_id: &'a str,
110 ccdm: &'a str,
111 xbm: &'a str,
112 }
113
114 let query_do_data = QueryDoWithCouresIdRequestData {
115 filter_list: q.into(),
116 xkxqm: self.use_store("xkxqm"),
117 xkxnm: self.use_store("xkxnm"),
118 xkkz_id: self.use_store("firstXkkzId"),
119 bklx_id: self.use_store("bklx_id"),
120 kch_id: &part_display_res.use_first_kch_id()?,
121 njdm_id: self.use_store("njdm_id"),
122 xsbj: self.use_store("xsbj"),
123 xz: self.use_store("xz"),
124 mzm: self.use_store("mzm"),
125 kklxdm: self.use_store("firstKklxdm"),
126 bh_id: self.use_store("bh_id"),
127 xqh_id: self.use_store("xqh_id"),
128 xslbdm: self.use_store("xslbdm"),
129 zyfx_id: self.use_store("zyfx_id"),
130 jg_id: self.use_store("jg_id_1"),
131 ccdm: self.use_store("ccdm"),
132 xbm: self.use_store("xbm"),
133 };
134
135 #[derive(Deserialize, Debug)]
137 struct SelectCourseQueryDoWithCourseIdResponseInnerData {
138 do_jxb_id: String, jsxx: String, jxb_id: String, sksj: String, }
146
147 trace!("query_do request");
148
149 let query_do_res = self
150 .post(&Client::SELECT_COURSE_QUERY_DO_WITH_COURSE_ID_URL)
151 .form(&query_do_data)
152 .send()
153 .await?
154 .json::<Vec<SelectCourseQueryDoWithCourseIdResponseInnerData>>()
155 .await?;
156
157 debug!("query_do {:#?}", query_do_res);
158
159 let mut returndta = Course {
160 xkkz_id: self
161 .stores
162 .get("firstXkkzId")
163 .ok_or(Error::Missing("[firstXkkzId] when fetch_courses".into()))?
164 .into(),
165
166 kch_id: part_display_res.use_first_kch_id()?.into(),
167 jxb: vec![],
168 };
169
170 for item in query_do_res {
171 returndta.jxb.push(Jxb {
172 jxb_id: item.jxb_id,
173 do_id: item.do_jxb_id,
174 jsxx: item.jsxx,
175 sksj: item.sksj,
176 });
177 }
178
179 if returndta.jxb.is_empty() {
180 warn!("{} 查询教学班为空", q);
181 }
182
183 info!("获取课程信息成功");
184
185 debug!("课程信息 {:#?}", returndta);
186
187 Ok(returndta)
188 }
189}