From 2fa77a556e1d95eca6012c538bc2932a2b445611 Mon Sep 17 00:00:00 2001 From: himawari <54976075+guohuiyuan@users.noreply.github.com> Date: Thu, 2 Oct 2025 13:56:51 +0800 Subject: [PATCH] =?UTF-8?q?feat(route):=20=E6=B7=BB=E5=8A=A0=E5=93=88?= =?UTF-8?q?=E5=B0=94=E6=BB=A8=E5=B7=A5=E4=B8=9A=E5=A4=A7=E5=AD=A6=EF=BC=88?= =?UTF-8?q?=E6=B7=B1=E5=9C=B3=EF=BC=89=E7=9A=84=E6=95=99=E5=8A=A1=E5=A4=84?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E7=9A=84=E8=B7=AF=E7=94=B1=20(#20108)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ✨ 添加哈公深教务处 * 🎨 修改拼接逻辑 * 🐛 修改const错误 * ✨ 添加按页数查,按时间排序 * 🎨 加速运行 * ✨ 添加教务管理 * 🎨 教务学务分离出来 * 🎨 优化速度 * 🔥 删除教务动态 * 🐛 修改翻页问题 * ✨ 添加综合代码 * ✨ 添加类型筛选 * ⚡️ 修改pr评论问题 * 🎨 添加空值检查 * 🐛 修改pr的评论问题 * 🐛 修改评论问题 * 🐛 修改es问题 * 🎨 修改代码问题 * 🐛 去掉多余的promise * 🐛 使用通用sort和limit逻辑 * 🐛 不翻页 * 🐛 修改review问题 * 🐛 修改标题带日期的问题 * 🐛 优化标题 --- lib/routes/hitsz/due-tzgg.ts | 110 ++++++++++++++++++++++ lib/routes/hitsz/due.ts | 172 +++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 lib/routes/hitsz/due-tzgg.ts create mode 100644 lib/routes/hitsz/due.ts diff --git a/lib/routes/hitsz/due-tzgg.ts b/lib/routes/hitsz/due-tzgg.ts new file mode 100644 index 000000000..b278ac1af --- /dev/null +++ b/lib/routes/hitsz/due-tzgg.ts @@ -0,0 +1,110 @@ +import { Route } from '@/types'; +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import timezone from '@/utils/timezone'; + +export const handler = async () => { + const baseUrl = 'http://due.hitsz.edu.cn'; + const baseListPath = 'index/tzggqb'; + + // 只抓取第一页 + const firstPageUrl = new URL(`${baseListPath}.htm`, baseUrl).href; + + let response; + try { + response = await got(firstPageUrl); + } catch { + // 返回空结果 + return { + title: '哈尔滨工业大学(深圳)教务部通知公告', + description: '哈尔滨工业大学(深圳)教务部通知公告', + link: firstPageUrl, + item: [], + author: '哈尔滨工业大学(深圳)教务部', + }; + } + + const $ = load(response.data); + + // 获取页面标题 + const pageTitle = $('title').text().trim() || '哈尔滨工业大学(深圳)教务部通知公告'; + const author = '哈尔滨工业大学(深圳)教务部'; + + // 解析第一页的文章列表 + const listItems = $('ul.list-main-modular li').toArray(); + + const items = listItems + .map((el) => { + const $el = $(el); + const linkUrl = $el.find('a').attr('href'); + if (!linkUrl) { + return null; + } + + const title = $el.find('span').text().trim(); + const pubDateStr = $el.find('label').text().trim(); + + return { + title, + link: new URL(linkUrl, baseUrl).href, + pubDate: pubDateStr ? timezone(parseDate(pubDateStr), 8) : null, + description: title, + }; + }) + .filter(Boolean); + + return { + title: `${author} - ${pageTitle}`, + description: pageTitle, + link: firstPageUrl, + item: items, + author, + }; +}; + +// 保持 route 定义完全不变 +export const route: Route = { + path: '/due/tzgg', + name: '教务部', + url: 'due.hitsz.edu.cn', + maintainers: ['guohuiyuan'], + handler, + example: '/hitsz/due/tzgg', + parameters: {}, + description: `:::tip +订阅 [通知公告](http://due.hitsz.edu.cn/index/tzggqb.htm),其源网址为 \`http://due.hitsz.edu.cn/index/tzggqb.htm\`,请参考该 URL 指定部分构成参数,此时路由为 [\`/hitsz/due/tzgg\`](https://rsshub.app/hitsz/due/tzgg)。 +::: +如需获取教务学务和学位管理所有栏目的新闻汇总,请使用 [\`/hitsz/due/general\`](https://rsshub.app/hitsz/due/general) 路由。 + +
+更多栏目 + +| 栏目 | ID | +| - | - | +| [通知公告](http://due.hitsz.edu.cn/index/tzggqb.htm) | [tzgg](https://rsshub.app/hitsz/due/tzgg) | + +
+`, + categories: ['university'], + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportRadar: true, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + radar: [ + { + source: ['due.hitsz.edu.cn', 'due.hitsz.edu.cn/index/:id/list.htm'], + target: '/hitsz/due/:id', + }, + { + title: '通知公告', + source: ['due.hitsz.edu.cn/index/tzggqb.htm'], + target: '/hitsz/due/tzgg', + }, + ], +}; diff --git a/lib/routes/hitsz/due.ts b/lib/routes/hitsz/due.ts new file mode 100644 index 000000000..98fd12495 --- /dev/null +++ b/lib/routes/hitsz/due.ts @@ -0,0 +1,172 @@ +import { Route } from '@/types'; +import got from '@/utils/got'; +import { load } from 'cheerio'; +import { parseDate } from '@/utils/parse-date'; +import timezone from '@/utils/timezone'; + +export const handler = async (ctx) => { + const baseUrl = 'http://due.hitsz.edu.cn'; + + // 按类型分组(可直接用于 handler 中的逻辑判断) + const categoryGroups = { + // 教务核心业务(传统教务管理相关) + teaching: [ + 'jwxw/jwgl', // 教务管理 + 'jwxw/kwgl', // 考务管理 + 'jwxw/zcgl', // 注册管理 + 'jwxw/xkgl', // 选课管理 + 'jwxw/cjgl', // 成绩管理 + ], + + // 学籍相关(学生档案与身份管理) + studentStatus: [ + 'jwxw/xjgl_b_', // 学籍管理(本) + 'jwxw/xjgl_y_', // 学籍管理(研) + ], + + // 教学支持(辅助教学的资源与服务) + teachingSupport: [ + 'jwxw/jxxxh', // 教学信息化 + 'jwxw/jzxj', // 奖助学金 + ], + + // 学生培养(不同学段的培养动态) + education: [ + 'xwgl/bksxw', // 本科生新闻 + 'xwgl/ssxwpy/ktyzj', // 硕士学位培养 + 'xwgl/bsxwpy/qqhj1', // 博士学位培养 + ], + }; + + // 修改:将 query 参数改为 path 参数(PR评论要求:Use path parameter instead of search query) + const { type = 'all' } = ctx.req.param(); // 从路径参数获取,默认值 'all' + const validTypes = Object.keys(categoryGroups); + const validType = validTypes.includes(type) ? type : 'all'; // 容错:无效类型默认走 all + + // 根据类型选择对应栏目组 + const categories = validType === 'all' ? Object.values(categoryGroups).flat() : categoryGroups[validType]; + + // 并发抓取所有栏目的第一页 + // 修复 ESLint:替换 .catch(() => null) 为带日志的try/catch + const pagePromises = categories.map(async (category) => { + const pageUrl = new URL(`${category}.htm`, baseUrl).href; + try { + return await got(pageUrl); + } catch { + return null; + } + }); + const pageResponses = await Promise.all(pagePromises); + + // 提取所有文章链接 + // 修复:用flatMap替代for循环+push(同步逻辑优化) + const articlePromises = pageResponses.flatMap((response, i) => { + if (!response) { + return []; + } + + const category = categories[i]; + const $ = load(response.data); + const listItemsOnPage = $('ul.box-main-list li, .list-main li, .list-main-modular li').toArray(); + + // 原map逻辑不变 + return listItemsOnPage + .map((el) => { + const $el = $(el); + const linkUrl = $el.find('a').attr('href'); + if (!linkUrl) { + return null; + } // 过滤无链接项 + + const title = $el.find('span').text().trim(); + const pubDateStr = $el.find('label').text().trim(); + + return { + title, + link: new URL(linkUrl, baseUrl).href, + pubDate: pubDateStr ? timezone(parseDate(pubDateStr), 8) : null, + category, + description: title, // 使用标题作为描述 + }; + }) + .filter(Boolean); // 过滤 null 项 + }); + + // 获取所有文章详情 + const allResolvedItems = articlePromises.filter(Boolean); + + // 排序和截取 + const filteredItems = allResolvedItems.filter((item) => !item.title.includes('统一身份认证平台')); + + return { + title: '哈尔滨工业大学(深圳)教务部-教务学务与学位管理-所有栏目新闻汇总', + description: '哈尔滨工业大学(深圳)教务部中教务学务和学位管理所有栏目的最新新闻汇总,包括教务管理、考务管理、注册管理、选课管理、成绩管理、学籍管理、教学信息化、奖助学金、本科生新闻、硕士学位培养、博士学位培养等', + link: 'http://due.hitsz.edu.cn/jwxw/jwgl.htm', + item: filteredItems, + author: '哈尔滨工业大学(深圳)教务部', + }; +}; + +export const route: Route = { + // 修改:path 增加可选参数 :type?(适配路径参数逻辑) + path: '/due/general/:type?', + name: '教务部教务学务与学位管理所有栏目', + url: 'due.hitsz.edu.cn', + maintainers: ['guohuiyuan'], + handler, + example: '/hitsz/due/general', + // 新增:补充 parameters 声明(修复PR评论的参数缺失问题) + parameters: { + type: { + description: '栏目类型筛选,默认all(所有栏目)', + options: [ + { value: 'all', label: '所有栏目' }, + { value: 'teaching', label: '教务核心业务' }, + { value: 'studentStatus', label: '学籍相关' }, + { value: 'teachingSupport', label: '教学支持' }, + { value: 'education', label: '学生培养' }, + ], + default: 'all', + }, + }, + // 修改:Markdown 二级标题##降级为四级标题####(PR评论要求:Do not use level 2 heading) + description: `哈尔滨工业大学(深圳)教务部中教务学务和学位管理所有栏目的最新新闻汇总。 + +#### 栏目分组说明 +支持按业务类型筛选,使用路径参数指定分组: +- \`type=teaching\` - 教务核心业务:教务管理、考务管理、注册管理、选课管理、成绩管理 +- \`type=studentStatus\` - 学籍相关:本科生学籍管理、研究生学籍管理 +- \`type=teachingSupport\` - 教学支持:教学信息化、奖助学金 +- \`type=education\` - 学生培养:本科生新闻、硕士学位培养、博士学位培养 +- \`type=all\` 或省略 - 所有栏目(默认) + +#### 包含栏目: +- [教务管理](http://due.hitsz.edu.cn/jwxw/jwgl.htm) +- [考务管理](http://due.hitsz.edu.cn/jwxw/kwgl.htm) +- [注册管理](http://due.hitsz.edu.cn/jwxw/zcgl.htm) +- [选课管理](http://due.hitsz.edu.cn/jwxw/xkgl.htm) +- [成绩管理](http://due.hitsz.edu.cn/jwxw/cjgl.htm) +- [学籍管理(本)](http://due.hitsz.edu.cn/jwxw/xjgl_b_.htm) +- [学籍管理(研)](http://due.hitsz.edu.cn/jwxw/xjgl_y_.htm) +- [教学信息化](http://due.hitsz.edu.cn/jwxw/jxxxh.htm) +- [奖助学金](http://due.hitsz.edu.cn/jwxw/jzxj.htm) +- [本科生新闻](http://due.hitsz.edu.cn/xwgl/bksxw.htm) +- [硕士学位培养](http://due.hitsz.edu.cn/xwgl/ssxwpy/ktyzj.htm) +- [博士学位培养](http://due.hitsz.edu.cn/xwgl/bsxwpy/qqhj1.htm)`, + categories: ['university'], + features: { + requireConfig: false, + requirePuppeteer: false, + antiCrawler: false, + supportRadar: true, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, + radar: [ + { + source: ['due.hitsz.edu.cn/jwxw/jwgl.htm'], + target: '/hitsz/due/general', + }, + ], +};