cust.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675
  1. // 文件: school.js
  2. // 长春理工大学教务系统课程表导入脚本
  3. // 检查是否在正确的页面
  4. function isOnStudentPage() {
  5. const url = window.location.href;
  6. return /jwgls[0-4]\.cust\.edu\.cn\/Student/i.test(url);
  7. }
  8. // 解析周数字符串(如 "1-8周[1-2节]" -> [1,2,3,4,5,6,7,8])
  9. function parseWeeks(timeStr) {
  10. const weeks = [];
  11. const weekMatch = timeStr.match(/(\d+)(?:-(\d+))?周/);
  12. if (weekMatch) {
  13. const start = parseInt(weekMatch[1]);
  14. const end = weekMatch[2] ? parseInt(weekMatch[2]) : start;
  15. for (let i = start; i <= end; i++) {
  16. weeks.push(i);
  17. }
  18. }
  19. return weeks;
  20. }
  21. // 解析节次字符串(如 "第1-2节" -> {start: 1, end: 2})
  22. function parseSections(sectionStr) {
  23. const match = sectionStr.match(/第(\d+)(?:-(\d+))?节/);
  24. if (match) {
  25. const start = parseInt(match[1]);
  26. const end = match[2] ? parseInt(match[2]) : start;
  27. return { start, end };
  28. }
  29. return null;
  30. }
  31. // 从API响应中提取并转换课程数据
  32. function convertScheduleData(apiData) {
  33. const coursesMap = new Map(); // 使用Map来临时存储和合并课程
  34. const timeSlots = new Set();
  35. // 遍历每一天
  36. apiData.data.AdjustDays.forEach(day => {
  37. const dayIndex = day.WIndex; // 1=周一, 7=周日
  38. // 处理所有时间段
  39. const allTimePieces = [
  40. ...(day.AM__TimePieces || []),
  41. ...(day.PM__TimePieces || []),
  42. ...(day.EV__TimePieces || [])
  43. ];
  44. allTimePieces.forEach(timePiece => {
  45. // 记录时间段
  46. if (timePiece.StartSection && timePiece.EndSection) {
  47. timeSlots.add(JSON.stringify({
  48. startSection: timePiece.StartSection,
  49. endSection: timePiece.EndSection,
  50. startTime: timePiece.StartTime,
  51. endTime: timePiece.EndTime
  52. }));
  53. }
  54. // 处理课程
  55. if (timePiece.Dtos && timePiece.Dtos.length > 0) {
  56. timePiece.Dtos.forEach(dto => {
  57. const content = dto.Content || [];
  58. // 提取课程信息
  59. let courseName = '';
  60. let teacher = [];
  61. let room = '';
  62. let weeks = [];
  63. let timeInfo = '';
  64. content.forEach(item => {
  65. switch(item.Key) {
  66. case 'Lesson':
  67. courseName = item.Name;
  68. break;
  69. case 'Teacher':
  70. teacher.push(item.Name);
  71. break;
  72. case 'Room':
  73. room = item.Name;
  74. break;
  75. case 'Time':
  76. timeInfo = item.Name;
  77. weeks = parseWeeks(item.Name);
  78. break;
  79. }
  80. });
  81. if (courseName && weeks.length > 0) {
  82. // 创建唯一键来识别相同的课程(同一天、同一课程、同一老师、同一地点、同一周次)
  83. const courseKey = `${dayIndex}-${courseName}-${teacher.join('、')}-${room}-${weeks.join(',')}`;
  84. if (coursesMap.has(courseKey)) {
  85. // 如果已存在,更新节次范围
  86. const existingCourse = coursesMap.get(courseKey);
  87. existingCourse.startSection = Math.min(existingCourse.startSection, timePiece.StartSection);
  88. existingCourse.endSection = Math.max(existingCourse.endSection, timePiece.EndSection);
  89. } else {
  90. // 如果不存在,创建新课程
  91. coursesMap.set(courseKey, {
  92. name: courseName,
  93. teacher: teacher.join('、'),
  94. position: room || '未指定',
  95. day: dayIndex,
  96. startSection: timePiece.StartSection,
  97. endSection: timePiece.EndSection,
  98. weeks: weeks
  99. });
  100. }
  101. }
  102. });
  103. }
  104. });
  105. });
  106. // 将Map转换为数组
  107. const courses = Array.from(coursesMap.values());
  108. // 按照星期和节次排序
  109. courses.sort((a, b) => {
  110. if (a.day !== b.day) return a.day - b.day;
  111. if (a.startSection !== b.startSection) return a.startSection - b.startSection;
  112. return a.endSection - b.endSection;
  113. });
  114. console.log(`合并后的课程数量: ${courses.length}`);
  115. return { courses, timeSlots: Array.from(timeSlots).map(s => JSON.parse(s)) };
  116. }
  117. // 获取课表数据
  118. async function fetchScheduleData() {
  119. try {
  120. console.log('正在获取课表数据...');
  121. // 构建请求参数(完整的参数结构)
  122. const requestData = {
  123. "param": "JTdCJTdE",
  124. "__permission": {
  125. "MenuID": "00000000-0000-0000-0000-000000000000",
  126. "Operate": "select",
  127. "Operation": 0
  128. },
  129. "__log": {
  130. "MenuID": "00000000-0000-0000-0000-000000000000",
  131. "Logtype": 6,
  132. "Context": "查询"
  133. }
  134. };
  135. // 获取当前域名
  136. const currentHost = window.location.hostname;
  137. const apiUrl = `https://${currentHost}/api/ClientStudent/Home/StudentHomeApi/QueryStudentScheduleData`;
  138. const response = await fetch(apiUrl, {
  139. method: 'POST',
  140. headers: {
  141. 'Accept': 'application/json, text/plain, */*',
  142. 'Content-Type': 'application/json;charset=UTF-8',
  143. 'Cache-Control': 'no-cache',
  144. 'Pragma': 'no-cache'
  145. },
  146. credentials: 'include',
  147. body: JSON.stringify(requestData)
  148. });
  149. if (!response.ok) {
  150. throw new Error(`HTTP error! status: ${response.status}`);
  151. }
  152. const data = await response.json();
  153. if (data.state !== 0) {
  154. throw new Error(data.message || '获取课表失败');
  155. }
  156. console.log('成功获取课表数据:', data);
  157. return data;
  158. } catch (error) {
  159. console.error('获取课表数据失败:', error);
  160. AndroidBridge.showToast('获取课表失败: ' + error.message);
  161. return null;
  162. }
  163. }
  164. // 生成时间段配置
  165. function generateTimeSlots(timeSlotsFromAPI) {
  166. const defaultTimeSlots = [
  167. { "number": 1, "startTime": "08:00", "endTime": "08:45" },
  168. { "number": 2, "startTime": "08:55", "endTime": "09:35" },
  169. { "number": 3, "startTime": "10:05", "endTime": "10:50" },
  170. { "number": 4, "startTime": "11:00", "endTime": "11:40" },
  171. { "number": 5, "startTime": "13:30", "endTime": "14:15" },
  172. { "number": 6, "startTime": "14:25", "endTime": "15:05" },
  173. { "number": 7, "startTime": "15:35", "endTime": "16:20" },
  174. { "number": 8, "startTime": "16:30", "endTime": "17:10" },
  175. { "number": 9, "startTime": "18:00", "endTime": "18:45" },
  176. { "number": 10, "startTime": "18:45", "endTime": "19:35" },
  177. { "number": 11, "startTime": "19:45", "endTime": "20:30" },
  178. { "number": 12, "startTime": "20:30", "endTime": "21:20" }
  179. ];
  180. // 如果API提供了时间信息,更新默认时间
  181. if (timeSlotsFromAPI && timeSlotsFromAPI.length > 0) {
  182. timeSlotsFromAPI.forEach(slot => {
  183. for (let i = slot.startSection; i <= slot.endSection; i++) {
  184. const timeSlot = defaultTimeSlots.find(t => t.number === i);
  185. if (timeSlot && i === slot.startSection) {
  186. timeSlot.startTime = slot.startTime;
  187. }
  188. if (timeSlot && i === slot.endSection) {
  189. timeSlot.endTime = slot.endTime;
  190. }
  191. }
  192. });
  193. }
  194. return defaultTimeSlots;
  195. }
  196. // 主函数:导入课程
  197. async function importCourseSchedule() {
  198. try {
  199. console.log('开始导入课程表...');
  200. AndroidBridge.showToast('正在获取课表数据...');
  201. // 获取课表数据
  202. const scheduleData = await fetchScheduleData();
  203. if (!scheduleData) {
  204. return false;
  205. }
  206. // 转换数据
  207. const { courses, timeSlots } = convertScheduleData(scheduleData);
  208. if (courses.length === 0) {
  209. AndroidBridge.showToast('未找到课程数据');
  210. return false;
  211. }
  212. console.log(`找到 ${courses.length} 门课程`);
  213. console.log('课程数据:', courses);
  214. // 导入课程
  215. const coursesResult = await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(courses));
  216. if (coursesResult === true) {
  217. console.log('课程导入成功!');
  218. AndroidBridge.showToast(`成功导入 ${courses.length} 门课程!`);
  219. } else {
  220. console.log('课程导入失败');
  221. AndroidBridge.showToast('课程导入失败');
  222. return false;
  223. }
  224. // 生成并导入时间段
  225. const finalTimeSlots = generateTimeSlots(timeSlots);
  226. console.log('时间段配置:', finalTimeSlots);
  227. const timeSlotsResult = await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(finalTimeSlots));
  228. if (timeSlotsResult === true) {
  229. console.log('时间段导入成功!');
  230. AndroidBridge.showToast('时间段配置成功!');
  231. } else {
  232. console.log('时间段导入失败');
  233. AndroidBridge.showToast('时间段配置失败');
  234. }
  235. return true;
  236. } catch (error) {
  237. console.error('导入过程出错:', error);
  238. AndroidBridge.showToast('导入失败: ' + error.message);
  239. return false;
  240. }
  241. }
  242. // ========== 以下是原有的演示函数(保留以供测试) ==========
  243. // 1. 显示一个公告信息弹窗
  244. async function demoAlert() {
  245. try {
  246. console.log("即将显示公告弹窗...");
  247. const confirmed = await window.AndroidBridgePromise.showAlert(
  248. "重要通知",
  249. "这是一个弹窗示例。",
  250. "好的"
  251. );
  252. if (confirmed) {
  253. console.log("用户点击了确认按钮。Alert Promise Resolved: " + confirmed);
  254. AndroidBridge.showToast("Alert:用户点击了确认!");
  255. return true; // 成功时返回 true
  256. } else {
  257. console.log("用户点击了取消按钮或关闭了弹窗。Alert Promise Resolved: " + confirmed);
  258. AndroidBridge.showToast("Alert:用户取消了!");
  259. return false; // 用户取消时返回 false
  260. }
  261. } catch (error) {
  262. console.error("显示公告弹窗时发生错误:", error);
  263. AndroidBridge.showToast("Alert:显示弹窗出错!" + error.message);
  264. return false; // 出现错误时也返回 false
  265. }
  266. }
  267. // 2. 显示带输入框的弹窗,并进行简单验证
  268. function validateName(name) {
  269. if (name === null || name.trim().length === 0) {
  270. return "输入不能为空!";
  271. }
  272. if (name.length < 2) {
  273. return "姓名至少需要2个字符!";
  274. }
  275. return false;
  276. }
  277. async function demoPrompt() {
  278. try {
  279. console.log("即将显示输入框弹窗...");
  280. const name = await window.AndroidBridgePromise.showPrompt(
  281. "输入你的姓名",
  282. "请输入至少2个字符",
  283. "测试用户",
  284. "validateName"
  285. );
  286. if (name !== null) {
  287. console.log("用户输入的姓名是: " + name);
  288. AndroidBridge.showToast("欢迎你," + name + "!");
  289. return true; // 成功时返回 true
  290. } else {
  291. console.log("用户取消了输入。");
  292. AndroidBridge.showToast("Prompt:用户取消了输入!");
  293. return false; // 用户取消时返回 false
  294. }
  295. } catch (error) {
  296. console.error("显示输入框弹窗时发生错误:", error);
  297. AndroidBridge.showToast("Prompt:显示输入框出错!" + error.message);
  298. return false; // 出现错误时也返回 false
  299. }
  300. }
  301. // 3. 显示一个单选列表弹窗
  302. async function demoSingleSelection() {
  303. const fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜", "芒果"];
  304. try {
  305. console.log("即将显示单选列表弹窗...");
  306. const selectedIndex = await window.AndroidBridgePromise.showSingleSelection(
  307. "选择你喜欢的水果",
  308. JSON.stringify(fruits),
  309. 2
  310. );
  311. if (selectedIndex !== null && selectedIndex >= 0 && selectedIndex < fruits.length) {
  312. console.log("用户选择了: " + fruits[selectedIndex] + " (索引: " + selectedIndex + ")");
  313. AndroidBridge.showToast("你选择了 " + fruits[selectedIndex]);
  314. return true; // 成功时返回 true
  315. } else {
  316. console.log("用户取消了选择。");
  317. AndroidBridge.showToast("Single Selection:用户取消了选择!");
  318. return false; // 用户取消时返回 false
  319. }
  320. } catch (error) {
  321. console.error("显示单选列表弹窗时发生错误:", error);
  322. AndroidBridge.showToast("Single Selection:显示列表出错!" + error.message);
  323. return false; // 出现错误时也返回 false
  324. }
  325. }
  326. // 仍然可以使用原始的 AndroidBridge 对象
  327. AndroidBridge.showToast("这是一个来自 JS 的 Toast 消息,会很快消失!");
  328. async function demoSaveCourses() {
  329. // ... 代码保持不变 ...
  330. console.log("正在准备测试课程数据...");
  331. const testCourses = [
  332. {
  333. "name": "高等数学",
  334. "teacher": "张教授",
  335. "position": "教101",
  336. "day": 1,
  337. "startSection": 1,
  338. "endSection": 2,
  339. "weeks": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  340. },
  341. {
  342. "name": "大学英语",
  343. "teacher": "李老师",
  344. "position": "文史楼203",
  345. "day": 1,
  346. "startSection": 2,
  347. "endSection": 4,
  348. "weeks": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
  349. },
  350. {
  351. "name": "数据结构",
  352. "teacher": "王副教授",
  353. "position": "信息楼B301",
  354. "day": 7,
  355. "startSection": 2,
  356. "endSection": 2,
  357. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  358. },
  359. {
  360. "name": "数据结构",
  361. "teacher": "王副教授",
  362. "position": "信息楼B301",
  363. "day": 7,
  364. "startSection": 3,
  365. "endSection": 3,
  366. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  367. },
  368. {
  369. "name": "数据结构",
  370. "teacher": "王副教授",
  371. "position": "信息楼B301",
  372. "day": 7,
  373. "startSection": 4,
  374. "endSection": 4,
  375. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  376. },
  377. {
  378. "name": "数据结构",
  379. "teacher": "王副教授",
  380. "position": "信息楼B301",
  381. "day": 7,
  382. "startSection": 5,
  383. "endSection": 5,
  384. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  385. },
  386. {
  387. "name": "数据结构",
  388. "teacher": "王副教授",
  389. "position": "信息楼B301",
  390. "day": 7,
  391. "startSection": 6,
  392. "endSection": 6,
  393. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  394. },
  395. {
  396. "name": "计算机组成原理",
  397. "teacher": "赵教授",
  398. "position": "实验楼401",
  399. "day": 4,
  400. "startSection": 4,
  401. "endSection": 4,
  402. "weeks": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  403. },
  404. {
  405. "name": "操作系统",
  406. "teacher": "钱副教授",
  407. "position": "信息楼C205",
  408. "day": 5,
  409. "startSection": 5,
  410. "endSection": 5,
  411. "weeks": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
  412. },
  413. {
  414. "name": "计算机网络",
  415. "teacher": "孙教授",
  416. "position": "信息楼D103",
  417. "day": 6,
  418. "startSection": 6,
  419. "endSection": 6,
  420. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  421. },
  422. {
  423. "name": "软件工程",
  424. "teacher": "周副教授",
  425. "position": "创新楼301",
  426. "day": 7,
  427. "startSection": 7,
  428. "endSection": 7,
  429. "weeks": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  430. },
  431. {
  432. "name": "数据库原理",
  433. "teacher": "吴教授",
  434. "position": "信息楼E201",
  435. "day": 1,
  436. "startSection": 8,
  437. "endSection": 8,
  438. "weeks": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
  439. },
  440. {
  441. "name": "人工智能",
  442. "teacher": "郑副教授",
  443. "position": "智能楼101",
  444. "day": 2,
  445. "startSection": 9,
  446. "endSection": 9,
  447. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  448. },
  449. {
  450. "name": "机器学习",
  451. "teacher": "冯教授",
  452. "position": "智能楼203",
  453. "day": 3,
  454. "startSection": 10,
  455. "endSection": 10,
  456. "weeks": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  457. },
  458. {
  459. "name": "编译原理",
  460. "teacher": "陈副教授",
  461. "position": "信息楼F105",
  462. "day": 4,
  463. "startSection": 11,
  464. "endSection": 11,
  465. "weeks": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
  466. },
  467. {
  468. "name": "计算机图形学",
  469. "teacher": "褚教授",
  470. "position": "图形楼301",
  471. "day": 5,
  472. "startSection": 12,
  473. "endSection": 12,
  474. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  475. },
  476. {
  477. "name": "网络安全",
  478. "teacher": "卫副教授",
  479. "position": "安全楼201",
  480. "day": 6,
  481. "startSection": 13,
  482. "endSection": 13,
  483. "weeks": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  484. },
  485. {
  486. "name": "分布式系统",
  487. "teacher": "蒋教授",
  488. "position": "云楼101",
  489. "day": 7,
  490. "startSection": 14,
  491. "endSection": 14,
  492. "weeks": [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
  493. },
  494. {
  495. "name": "大数据技术",
  496. "teacher": "沈副教授",
  497. "position": "数据楼301",
  498. "day": 1,
  499. "startSection": 15,
  500. "endSection": 15,
  501. "weeks": [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
  502. },
  503. {
  504. "name": "物联网技术",
  505. "teacher": "韩教授",
  506. "position": "物联楼201",
  507. "day": 2,
  508. "startSection": 16,
  509. "endSection": 16,
  510. "weeks": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
  511. }
  512. ];
  513. try {
  514. console.log("正在尝试导入课程...");
  515. const result = await window.AndroidBridgePromise.saveImportedCourses(JSON.stringify(testCourses));
  516. if (result === true) {
  517. console.log("课程导入成功!");
  518. AndroidBridge.showToast("测试课程导入成功!");
  519. } else {
  520. console.log("课程导入未成功,结果:" + result);
  521. AndroidBridge.showToast("测试课程导入失败,请查看日志。");
  522. }
  523. } catch (error) {
  524. console.error("导入课程时发生错误:", error);
  525. AndroidBridge.showToast("导入课程失败: " + error.message);
  526. }
  527. }
  528. // 5. 导入预设时间段(保持不变)
  529. async function importPresetTimeSlots() {
  530. console.log("正在准备预设时间段数据...");
  531. const presetTimeSlots = [
  532. { "number": 1, "startTime": "08:00", "endTime": "08:01" },
  533. { "number": 2, "startTime": "09:00", "endTime": "09:01" },
  534. { "number": 3, "startTime": "10:00", "endTime": "10:01" },
  535. { "number": 4, "startTime": "11:00", "endTime": "11:01" },
  536. { "number": 5, "startTime": "12:00", "endTime": "12:01" },
  537. { "number": 6, "startTime": "13:00", "endTime": "13:01" },
  538. { "number": 7, "startTime": "14:00", "endTime": "14:01" },
  539. { "number": 8, "startTime": "15:00", "endTime": "15:01" },
  540. { "number": 9, "startTime": "16:00", "endTime": "16:01" },
  541. { "number": 10, "startTime": "17:00", "endTime": "17:01" },
  542. { "number": 11, "startTime": "18:00", "endTime": "18:01" },
  543. { "number": 12, "startTime": "19:00", "endTime": "19:01" },
  544. { "number": 13, "startTime": "20:00", "endTime": "20:01" },
  545. { "number": 14, "startTime": "21:00", "endTime": "21:01" },
  546. { "number": 15, "startTime": "22:00", "endTime": "22:01" },
  547. { "number": 16, "startTime": "23:00", "endTime": "23:01" }
  548. ];
  549. try {
  550. console.log("正在尝试导入预设时间段...");
  551. const result = await window.AndroidBridgePromise.savePresetTimeSlots(JSON.stringify(presetTimeSlots));
  552. if (result === true) {
  553. console.log("预设时间段导入成功!");
  554. window.AndroidBridge.showToast("测试时间段导入成功!");
  555. } else {
  556. console.log("预设时间段导入未成功,结果:" + result);
  557. window.AndroidBridge.showToast("测试时间段导入失败,请查看日志。");
  558. }
  559. } catch (error) {
  560. console.error("导入时间段时发生错误:", error);
  561. window.AndroidBridge.showToast("导入时间段失败: " + error.message);
  562. }
  563. }
  564. /**
  565. * 编排这些异步操作,并在用户取消时停止后续执行。
  566. */
  567. async function runAllDemosSequentially() {
  568. AndroidBridge.showToast("所有演示将按顺序开始...");
  569. // 1. 运行第一个演示:Alert
  570. const alertResult = await demoAlert();
  571. if (!alertResult) {
  572. console.log("用户取消了 Alert 演示,停止后续执行。");
  573. return; // 用户取消,立即退出函数
  574. }
  575. // 2. 运行第二个演示:Prompt
  576. const promptResult = await demoPrompt();
  577. if (!promptResult) {
  578. console.log("用户取消了 Prompt 演示,停止后续执行。");
  579. return; // 用户取消,立即退出函数
  580. }
  581. // 3. 运行第三个演示:SingleSelection
  582. const selectionResult = await demoSingleSelection();
  583. if (!selectionResult) {
  584. console.log("用户取消了 Single Selection 演示,停止后续执行。");
  585. return; // 用户取消,立即退出函数
  586. }
  587. console.log("所有弹窗演示已完成。");
  588. AndroidBridge.showToast("所有弹窗演示已完成!");
  589. // 以下是数据导入,与用户交互无关,可以继续
  590. await demoSaveCourses();
  591. await importPresetTimeSlots();
  592. // 发送最终的生命周期完成信号
  593. AndroidBridge.notifyTaskCompletion();
  594. }
  595. // ========== 主执行逻辑 ==========
  596. // 检查页面并执行相应操作
  597. if (isOnStudentPage()) {
  598. console.log('检测到在长春理工大学教务系统学生页面');
  599. AndroidBridge.showToast('正在准备导入课程表...');
  600. // 延迟一秒确保页面加载完成
  601. setTimeout(async () => {
  602. const success = await importCourseSchedule();
  603. if (success) {
  604. AndroidBridge.notifyTaskCompletion();
  605. }
  606. }, 1000);
  607. } else {
  608. console.log('当前不在教务系统页面,运行演示模式');
  609. AndroidBridge.showToast('请先登录教务系统!');
  610. // 可选:运行演示
  611. const runDemo = false; // 设为true可以运行演示
  612. if (runDemo) {
  613. runAllDemosSequentially();
  614. }
  615. }