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::{
8        ToJson,
9        macros::{debug, info, trace, warn},
10    },
11};
12
13impl Client {
14    /// 查询教学班参数,需要精确的搜索
15    pub async fn fetch_courses(&self, q: &str) -> R<Course> {
16        info!("查询课程,q: {}", q);
17
18        #[derive(Serialize, Debug)]
19        struct PartDisplayRequestData<'a> {
20            #[serde(rename = "filter_list[0]")]
21            filter_list: &'a str,
22            xbm: &'a str,
23            ccdm: &'a str,
24            kklxdm: &'a str,
25            xkxnm: &'a str, //选课学年:如 “2024”
26            xkxqm: &'a str, //选课学期名,如第二学期为 “2”
27            jg_id: &'a str, // 二级学院 id
28            xsbj: &'a str,  //学生班级(推测)
29            mzm: &'a str,
30            xz: &'a str,      //可能是学制
31            bh_id: &'a str,   //学生班级号id,值为完整学号去除后两位
32            xqh_id: &'a str,  //学区号id(推测)
33            zyfx_id: &'a str, //与专业有关
34            xslbdm: &'a str,
35            kspage: &'a str,
36            jspage: &'a str,
37        }
38
39        let part_display_data = PartDisplayRequestData {
40            filter_list: q.into(),
41            xbm: self.use_store("xbm"),
42            ccdm: self.use_store("ccdm"),
43            kklxdm: self.use_store("firstKklxdm"),
44            xkxnm: self.use_store("xkxnm"),
45            xkxqm: self.use_store("xkxqm"),
46            jg_id: self.use_store("jg_id_1"),
47            xsbj: self.use_store("xsbj"),
48            mzm: self.use_store("mzm"),
49            xz: self.use_store("xz"),
50            bh_id: self.use_store("bh_id"),
51            xqh_id: self.use_store("xqh_id"),
52            zyfx_id: self.use_store("zyfx_id"),
53            xslbdm: self.use_store("xslbdm"),
54            kspage: "1",
55            jspage: "10",
56        };
57
58        #[derive(Deserialize, Debug)]
59        struct PartDisplayResponseData {
60            #[serde(rename = "tmpList")]
61            tmp_list: Vec<PartDisplayResponseInnerData>,
62        }
63
64        impl PartDisplayResponseData {
65            fn use_first_kch_id(&self) -> R<&String> {
66                Ok(&self
67                    .tmp_list
68                    .get(0)
69                    .ok_or(Error::JxbNotFound("~.tmp_list.0"))?
70                    .kch_id)
71            }
72        }
73
74        #[derive(Deserialize, Debug)]
75        struct PartDisplayResponseInnerData {
76            // jxb_id: String, //教学班id
77            // jxbmc: String,  //教学班名称 (2024-2025-2)-40190004-25
78            // kcmc: String,   //课程名称
79            kch_id: String, //课程号
80        }
81
82        trace!("part_display request");
83
84        let part_display_res = self
85            .post(&Client::SELECT_COURSE_PART_DISPLAY_URL)
86            .form(&part_display_data)
87            .send()
88            .await?
89            .jsonr::<PartDisplayResponseData>()
90            .await?;
91
92        debug!("part_display {:#?}", part_display_res);
93
94        #[derive(Serialize, Debug)]
95        struct QueryDoWithCouresIdRequestData<'a> {
96            #[serde(rename = "filter_list[0]")]
97            filter_list: &'a str,
98            xkxqm: &'a str,
99            xkxnm: &'a str,
100            xkkz_id: &'a str,
101            bklx_id: &'a str,
102            kch_id: &'a str,  // 课程号
103            njdm_id: &'a str, //年级名称
104            xsbj: &'a str,
105            xz: &'a str, //学制
106            mzm: &'a str,
107            kklxdm: &'a str,
108            bh_id: &'a str,
109            xqh_id: &'a str,
110            xslbdm: &'a str,
111            zyfx_id: &'a str,
112            jg_id: &'a str,
113            ccdm: &'a str,
114            xbm: &'a str,
115        }
116
117        let query_do_data = QueryDoWithCouresIdRequestData {
118            filter_list: q.into(),
119            xkxqm: self.use_store("xkxqm"),
120            xkxnm: self.use_store("xkxnm"),
121            xkkz_id: self.use_store("firstXkkzId"),
122            bklx_id: self.use_store("bklx_id"),
123            kch_id: &part_display_res.use_first_kch_id()?,
124            njdm_id: self.use_store("njdm_id"),
125            xsbj: self.use_store("xsbj"),
126            xz: self.use_store("xz"),
127            mzm: self.use_store("mzm"),
128            kklxdm: self.use_store("firstKklxdm"),
129            bh_id: self.use_store("bh_id"),
130            xqh_id: self.use_store("xqh_id"),
131            xslbdm: self.use_store("xslbdm"),
132            zyfx_id: self.use_store("zyfx_id"),
133            jg_id: self.use_store("jg_id_1"),
134            ccdm: self.use_store("ccdm"),
135            xbm: self.use_store("xbm"),
136        };
137
138        // #[allow(unused)]
139        #[derive(Deserialize, Debug)]
140        struct SelectCourseQueryDoWithCourseIdResponseInnerData {
141            //返回值是一个列表
142            do_jxb_id: String, //执行id
143            jsxx: String,      //教师信息
144            jxb_id: String,    //教学班id
145            // jxdd: String,      //教学地点
146            sksj: String, //上课时间  星期四第9-10节{9-16周}
147                          // xqumc: String,     //校区名称
148        }
149
150        trace!("query_do request");
151
152        let query_do_res = self
153            .post(&Client::SELECT_COURSE_QUERY_DO_WITH_COURSE_ID_URL)
154            .form(&query_do_data)
155            .send()
156            .await?
157            .jsonr::<Vec<SelectCourseQueryDoWithCourseIdResponseInnerData>>()
158            .await?;
159
160        debug!("query_do {:#?}", query_do_res);
161
162        let mut returndta = Course {
163            xkkz_id: self
164                .stores
165                .get("firstXkkzId")
166                .ok_or(Error::Missing("[firstXkkzId] when fetch_courses".into()))?
167                .into(),
168
169            kch_id: part_display_res.use_first_kch_id()?.into(),
170            jxb: vec![],
171        };
172
173        for item in query_do_res {
174            returndta.jxb.push(Jxb {
175                jxb_id: item.jxb_id,
176                do_id: item.do_jxb_id,
177                jsxx: item.jsxx,
178                sksj: item.sksj,
179            });
180        }
181
182        if returndta.jxb.is_empty() {
183            warn!("{} 查询教学班为空", q);
184        }
185
186        info!("获取课程信息成功");
187
188        debug!("课程信息 {:#?}", returndta);
189
190        Ok(returndta)
191    }
192}