hquadap.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * 华侨大学 (HQU) 教务系统课程导入脚本
  3. * 版本:2026 春季学期
  4. * 还有待解决的问题:课程合并
  5. */
  6. // 1. 全局验证函数 (由 showPrompt 调用)
  7. function validateTermInput(input) {
  8. if (/^\d{4}-\d{4}-\d$/.test(input)) {
  9. return false; // 校验通过
  10. } else {
  11. return "格式错误!请输入如 2025-2026-2";
  12. }
  13. }
  14. async function runImportFlow() {
  15. AndroidBridge.showToast("正在启动华大教务同步程序...");
  16. try {
  17. // --- 1. 获取学期代码 ---
  18. const termQuery = [
  19. { name: "CSDM", linkOpt: "AND", builderList: "cbl_String", builder: "equal", value: "PK" },
  20. { name: "ZCSDM", linkOpt: "AND", builderList: "cbl_String", builder: "equal", value: "XSDXNXQDM" }
  21. ];
  22. const termResp = await fetch("https://jwapp-hqu-edu-cn-s.atrust.hqu.edu.cn:9443/jwapp/sys/wdkb/modules/xskcb/xtcscx.do?sf_request_type=ajax", {
  23. method: "POST",
  24. headers: { "content-type": "application/x-www-form-urlencoded" },
  25. body: `querySetting=${encodeURIComponent(JSON.stringify(termQuery))}`
  26. });
  27. const termJson = await termResp.json();
  28. const currentXNXQ = termJson.datas.xtcscx.CSZA || "2025-2026-2";
  29. const parts = currentXNXQ.split('-');
  30. const currentXN = `${parts}-${parts}`;
  31. const currentXQ = parts;
  32. // --- 2. 获取配置与开学日期 ---
  33. let startDate = "2026-03-02";
  34. let totalWeeks = 18;
  35. try {
  36. const configResp = await fetch("https://jwapp-hqu-edu-cn-s.atrust.hqu.edu.cn:9443/jwapp/sys/wdkb/modules/jshkcb/cxjcs.do?sf_request_type=ajax", {
  37. method: "POST",
  38. headers: { "content-type": "application/x-www-form-urlencoded" },
  39. body: `XN=${currentXN}&XQ=${currentXQ}`
  40. });
  41. const configJson = await configResp.json();
  42. const schoolConfig = configJson.datas.cxjcs.rows;
  43. if (schoolConfig && schoolConfig.XQKSRQ) {
  44. startDate = schoolConfig.XQKSRQ.split(' ');
  45. totalWeeks = parseInt(schoolConfig.ZZC) || 18;
  46. }
  47. } catch (e) { console.log("配置抓取跳过"); }
  48. // --- 3. 抓取课表详情 ---
  49. const kbResp = await fetch("https://jwapp-hqu-edu-cn-s.atrust.hqu.edu.cn:9443/jwapp/sys/wdkb/modules/xskcb/cxxszhxqkb.do?sf_request_type=ajax", {
  50. method: "POST",
  51. headers: { "content-type": "application/x-www-form-urlencoded" },
  52. body: `XNXQDM=${currentXNXQ}&XNXQDM2=${currentXNXQ}&XNXQDM3=${currentXNXQ}`
  53. });
  54. const kbJson = await kbResp.json();
  55. const rawRows = kbJson.datas.cxxszhxqkb.rows;
  56. //转换数据结构
  57. const parsedCourses = rawRows.map(item => {
  58. // 1. 周次解析:从位图获取最硬核的数据
  59. const weeks = [];
  60. const bitMap = item.SKZC || "";
  61. // 华大逻辑:如果位图索引1是1,那就是第一周有课 你看它里面 "SKZC": "011111111111111100",
  62. for (let i = 0; i < bitMap.length; i++) {
  63. if (bitMap[i] === '1') {
  64. weeks.push(i + 1);
  65. }
  66. }
  67. // 体育课的标题:体育课加上具体的项目(如:篮球)
  68. let courseName = item.KCM;
  69. if (item.TYXMDM_DISPLAY) {
  70. courseName = `${courseName}(${item.TYXMDM_DISPLAY})`;
  71. }
  72. // 地点兜底:优先取具体教室,没有则取教学楼,再没有则标记操场
  73. const position = item.JASMC || item.JXLDM_DISPLAY || "操场/待定";
  74. // 2. YPSJDD
  75. let note = `原始安排:${item.YPSJDD || '无'}`;
  76. if (item.XF) note += `\n学分:${item.XF}`;
  77. if (item.KCXZDM_DISPLAY) note += `\n性质:${item.KCXZDM_DISPLAY}`;
  78. return {
  79. name: item.KCM,
  80. teacher: item.SKJS || item.JSM || "未知",
  81. position: position,
  82. day: parseInt(item.SKXQ),
  83. startSection: parseInt(item.KSJC),
  84. endSection: parseInt(item.JSJC),
  85. weeks: weeks,
  86. };
  87. });
  88. // --- 5. 提交数据 ---
  89. await window.AndroidBridgePromise.saveCourseConfig(JSON.stringify({
  90. semesterStartDate: startDate,
  91. semesterTotalWeeks: totalWeeks
  92. }));
  93. const timeSlots = [
  94. { number: 1, startTime: "08:00", endTime: "08:45" }, { number: 2, startTime: "08:55", endTime: "09:40" },
  95. { number: 3, startTime: "10:00", endTime: "10:45" }, { number: 4, startTime: "10:55", endTime: "11:40" },
  96. { number: 5, startTime: "11:45", endTime: "12:30" }, { number: 6, startTime: "14:30", endTime: "15:15" },
  97. { number: 7, startTime: "15:25", endTime: "16:10" }, { number: 8, startTime: "16:20", endTime: "17:05" },
  98. { number: 9, startTime: "17:15", endTime: "18:00" }, { number: 10, startTime: "18:20", endTime: "19:05" },
  99. { number: 11, startTime: "19:10", endTime: "19:55" }, { number: 12, startTime: "20:05", endTime: "20:50" },
  100. { number: 13, startTime: "20:55", endTime: "21:40" }
  101. ];
  102. await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(timeSlots));
  103. await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(parsedCourses));
  104. AndroidBridge.showToast(`${currentXNXQ} 导入成功!`);
  105. AndroidBridge.notifyTaskCompletion();
  106. } catch (e) {
  107. await window.AndroidBridgePromise.showAlert("导入失败", "错误: " + e.message, "重试");
  108. }
  109. }
  110. runImportFlow();