Skip to main content

lnu_elytra/method/
fetch_course.rs

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    /// 查询教学班参数,需要精确的搜索
12    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, //选课学年:如 “2024”
23            xkxqm: &'a str, //选课学期名,如第二学期为 “2”
24            jg_id: &'a str, // 二级学院 id
25            xsbj: &'a str,  //学生班级(推测)
26            mzm: &'a str,
27            xz: &'a str,      //可能是学制
28            bh_id: &'a str,   //学生班级号id,值为完整学号去除后两位
29            xqh_id: &'a str,  //学区号id(推测)
30            zyfx_id: &'a str, //与专业有关
31            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            // jxb_id: String, //教学班id
74            // jxbmc: String,  //教学班名称 (2024-2025-2)-40190004-25
75            // kcmc: String,   //课程名称
76            kch_id: String, //课程号
77        }
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,  // 课程号
100            njdm_id: &'a str, //年级名称
101            xsbj: &'a str,
102            xz: &'a str, //学制
103            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        // #[allow(unused)]
136        #[derive(Deserialize, Debug)]
137        struct SelectCourseQueryDoWithCourseIdResponseInnerData {
138            //返回值是一个列表
139            do_jxb_id: String, //执行id
140            jsxx: String,      //教师信息
141            jxb_id: String,    //教学班id
142            // jxdd: String,      //教学地点
143            sksj: String, //上课时间  星期四第9-10节{9-16周}
144                          // xqumc: String,     //校区名称
145        }
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}