|
@@ -1,7 +1,22 @@
|
|
|
const BASE = `${window.location.origin}/jwglxt`;
|
|
const BASE = `${window.location.origin}/jwglxt`;
|
|
|
const INDEX_PATH = '/kbcx/xskbcx_cxXskbcxIndex.html?gnmkdm=N2151&layout=default';
|
|
const INDEX_PATH = '/kbcx/xskbcx_cxXskbcxIndex.html?gnmkdm=N2151&layout=default';
|
|
|
const COURSE_API_PATH = '/kbcx/xskbcx_cxXsgrkb.html?gnmkdm=N2151';
|
|
const COURSE_API_PATH = '/kbcx/xskbcx_cxXsgrkb.html?gnmkdm=N2151';
|
|
|
-const TIME_API_PATH = '/kbcx/xskbcx_cxRjc.html?gnmkdm=N2151';
|
|
|
|
|
|
|
+
|
|
|
|
|
+const TIME_SLOTS = [
|
|
|
|
|
+ { number: 1, startTime: '08:10', endTime: '08:50' },
|
|
|
|
|
+ { number: 2, startTime: '09:00', endTime: '09:40' },
|
|
|
|
|
+ { number: 3, startTime: '09:50', endTime: '10:30' },
|
|
|
|
|
+ { number: 4, startTime: '10:40', endTime: '11:20' },
|
|
|
|
|
+ { number: 5, startTime: '11:30', endTime: '12:10' },
|
|
|
|
|
+ { number: 6, startTime: '14:10', endTime: '14:50' },
|
|
|
|
|
+ { number: 7, startTime: '15:00', endTime: '15:40' },
|
|
|
|
|
+ { number: 8, startTime: '15:50', endTime: '16:30' },
|
|
|
|
|
+ { number: 9, startTime: '16:40', endTime: '17:20' },
|
|
|
|
|
+ { number: 10, startTime: '18:30', endTime: '19:10' },
|
|
|
|
|
+ { number: 11, startTime: '19:20', endTime: '20:00' },
|
|
|
|
|
+ { number: 12, startTime: '20:10', endTime: '20:50' },
|
|
|
|
|
+ { number: 13, startTime: '21:00', endTime: '21:40' },
|
|
|
|
|
+];
|
|
|
|
|
|
|
|
async function req(url, method = 'GET', body) {
|
|
async function req(url, method = 'GET', body) {
|
|
|
const res = await fetch(url, {
|
|
const res = await fetch(url, {
|
|
@@ -151,66 +166,30 @@ function parseCourses(data) {
|
|
|
return { courses: [...deduped.values()], xqhId };
|
|
return { courses: [...deduped.values()], xqhId };
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function parseTimeSlots(data) {
|
|
|
|
|
- if (!Array.isArray(data) || !data.length) throw new Error('未获取到节次时间数据');
|
|
|
|
|
- return data.map((item) => ({
|
|
|
|
|
- number: Number(item.jcmc),
|
|
|
|
|
- startTime: String(item.qssj || '').trim(),
|
|
|
|
|
- endTime: String(item.jssj || '').trim()
|
|
|
|
|
- })).filter(item => item.number > 0 && item.startTime && item.endTime);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
async function fetchCourses(xnm, xqm) {
|
|
async function fetchCourses(xnm, xqm) {
|
|
|
const body = `xnm=${encodeURIComponent(xnm)}&xqm=${encodeURIComponent(xqm)}&kzlx=ck&xsdm=&kclbdm=&kclxdm=`;
|
|
const body = `xnm=${encodeURIComponent(xnm)}&xqm=${encodeURIComponent(xqm)}&kzlx=ck&xsdm=&kclbdm=&kclxdm=`;
|
|
|
const text = await req(`${BASE}${COURSE_API_PATH}`, 'POST', body);
|
|
const text = await req(`${BASE}${COURSE_API_PATH}`, 'POST', body);
|
|
|
return JSON.parse(text);
|
|
return JSON.parse(text);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-async function fetchTimeSlots(xnm, xqm, xqhId) {
|
|
|
|
|
- const body = `xnm=${encodeURIComponent(xnm)}&xqm=${encodeURIComponent(xqm)}&xqh_id=${encodeURIComponent(xqhId || '1')}`;
|
|
|
|
|
- const text = await req(`${BASE}${TIME_API_PATH}`, 'POST', body);
|
|
|
|
|
- return parseTimeSlots(JSON.parse(text));
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function validateSemesterStartDateInput(input) {
|
|
|
|
|
- const value = String(input || '').trim();
|
|
|
|
|
- if (!value) return false;
|
|
|
|
|
- return /^\d{4}-\d{2}-\d{2}$/.test(value) ? false : '请输入 YYYY-MM-DD,例如 2026-02-24';
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-async function selectSemesterStartDate(xnm, xqm) {
|
|
|
|
|
- const defaultDate = xqm === '3' ? `${xnm}-09-01` : `${Number(xnm) + 1}-03-01`;
|
|
|
|
|
- const picked = await window.AndroidBridgePromise.showPrompt(
|
|
|
|
|
- '选择开学日期',
|
|
|
|
|
- '请输入开学日期(YYYY-MM-DD)',
|
|
|
|
|
- defaultDate,
|
|
|
|
|
- 'validateSemesterStartDateInput'
|
|
|
|
|
- );
|
|
|
|
|
- if (picked === null) return null;
|
|
|
|
|
- const value = String(picked).trim();
|
|
|
|
|
- return value || null;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
async function run() {
|
|
async function run() {
|
|
|
try {
|
|
try {
|
|
|
const { xnm, xqm } = await resolveTerm();
|
|
const { xnm, xqm } = await resolveTerm();
|
|
|
AndroidBridge.showToast('正在解析课表数据...');
|
|
AndroidBridge.showToast('正在解析课表数据...');
|
|
|
|
|
|
|
|
const rawData = await fetchCourses(xnm, xqm);
|
|
const rawData = await fetchCourses(xnm, xqm);
|
|
|
- const { courses, xqhId } = parseCourses(rawData);
|
|
|
|
|
|
|
+ const { courses } = parseCourses(rawData);
|
|
|
if (!courses.length) throw new Error('未获取到课表数据');
|
|
if (!courses.length) throw new Error('未获取到课表数据');
|
|
|
|
|
|
|
|
- const semesterStartDate = await selectSemesterStartDate(xnm, xqm);
|
|
|
|
|
- const timeSlots = await fetchTimeSlots(xnm, xqm, xqhId);
|
|
|
|
|
const allWeeks = courses.flatMap(course => course.weeks);
|
|
const allWeeks = courses.flatMap(course => course.weeks);
|
|
|
const semesterTotalWeeks = allWeeks.length ? Math.max(...allWeeks) : 20;
|
|
const semesterTotalWeeks = allWeeks.length ? Math.max(...allWeeks) : 20;
|
|
|
|
|
|
|
|
await window.AndroidBridgePromise.saveCourseConfig(JSON.stringify({
|
|
await window.AndroidBridgePromise.saveCourseConfig(JSON.stringify({
|
|
|
semesterTotalWeeks,
|
|
semesterTotalWeeks,
|
|
|
- semesterStartDate,
|
|
|
|
|
|
|
+ semesterStartDate: null,
|
|
|
firstDayOfWeek: 1
|
|
firstDayOfWeek: 1
|
|
|
}));
|
|
}));
|
|
|
- await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(timeSlots));
|
|
|
|
|
|
|
+ await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(TIME_SLOTS));
|
|
|
await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(courses));
|
|
await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(courses));
|
|
|
|
|
|
|
|
AndroidBridge.showToast(`导入成功:${courses.length} 门`);
|
|
AndroidBridge.showToast(`导入成功:${courses.length} 门`);
|