diff --git a/docs/university.md b/docs/university.md
index 71a9f5b7b..cb0dd2754 100644
--- a/docs/university.md
+++ b/docs/university.md
@@ -2021,6 +2021,16 @@ type 列表:
+### 教务处
+
+
+
+| 规章制度 | 专业建设 | 实践教学 | 支部风采 | 服务指南 | 教务要闻 | 工作通知 | 教务简报 | 常用下载 |
+| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
+| gzzd | zyjs | sjjx | zbfc | fwzn | jwyw | gztz | jwjb | cyxz |
+
+
+
## 上海大学
### 上海大学官网信息
diff --git a/lib/v2/sdu/data.js b/lib/v2/sdu/data.js
index c9c1da953..00b5d6919 100644
--- a/lib/v2/sdu/data.js
+++ b/lib/v2/sdu/data.js
@@ -3,7 +3,7 @@ module.exports = {
news: {
name: '山东大学(威海)新闻网',
route: '/news',
- source: ['/'],
+ source: ['/*path', '/'],
titlePrefix: '(威海)新闻网|',
docs: 'https://docs.rsshub.app/university.html#shan-dong-da-xue-wei-hai',
getTarget(url) {
@@ -57,5 +57,54 @@ module.exports = {
},
},
},
+ jwc: {
+ name: '山东大学(威海)教务处',
+ route: '/jwc',
+ source: ['/*path', '/'],
+ titlePrefix: '(威海)教务处|',
+ docs: 'https://docs.rsshub.app/university.html#shan-dong-da-xue-wei-hai',
+ getTarget(url) {
+ return this.route + '/' + url.replace(/\.htm$/, '');
+ },
+ url: 'https://jwc.wh.sdu.edu.cn/',
+ columns: {
+ gzzd: {
+ name: '规章制度',
+ url: 'gzzd.htm',
+ },
+ zyjs: {
+ name: '专业建设',
+ url: 'zyjs.htm',
+ },
+ sjjx: {
+ name: '实践教学',
+ url: 'sjjx.htm',
+ },
+ zbfc: {
+ name: '支部风采',
+ url: 'zbfc.htm',
+ },
+ fwzn: {
+ name: '服务指南',
+ url: 'fwzn.htm',
+ },
+ jwyw: {
+ name: '教务要闻',
+ url: 'jwyw.htm',
+ },
+ gztz: {
+ name: '工作通知',
+ url: 'gztz.htm',
+ },
+ jwjb: {
+ name: '教务简报',
+ url: 'jwjb.htm',
+ },
+ cyxz: {
+ name: '常用下载',
+ url: 'cyxz.htm',
+ },
+ },
+ },
},
};
diff --git a/lib/v2/sdu/extractor/index.js b/lib/v2/sdu/extractor/index.js
index de1fc1979..97cc11178 100644
--- a/lib/v2/sdu/extractor/index.js
+++ b/lib/v2/sdu/extractor/index.js
@@ -8,5 +8,8 @@ module.exports = async (link, ctx) => {
if (link.startsWith('https://www.sdrj.sdu.edu.cn/')) {
return await require('./sdrj')(link, ctx);
}
+ if (link.startsWith('https://jwc.wh.sdu.edu.cn/')) {
+ return await require('./wh/jwc')(link, ctx);
+ }
return {};
};
diff --git a/lib/v2/sdu/extractor/wh/jwc.js b/lib/v2/sdu/extractor/wh/jwc.js
new file mode 100644
index 000000000..18e06ace2
--- /dev/null
+++ b/lib/v2/sdu/extractor/wh/jwc.js
@@ -0,0 +1,24 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const timezone = require('@/utils/timezone');
+
+module.exports = async (link, ctx) =>
+ await ctx.cache.tryGet(link, async () => {
+ let content, exactDate;
+ try {
+ const result = await got(link);
+ const $ = cheerio.load(result.data);
+ const form = $("form[name='_newscontent_fromname']");
+ form.find('h2').remove();
+ const exactDateElement = form.find('#author');
+ const exactDateStr = exactDateElement.text();
+ exactDateElement.remove();
+ content = form.html();
+ const exactDateText = exactDateStr.match(/^创建时间:(?\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})/).groups.date;
+ exactDate = timezone(parseDate(exactDateText, 'YYYY-MM-DD HH:mm:ss'), +8);
+ return { description: content, exactDate };
+ } catch (e) {
+ return { description: content, exactDate };
+ }
+ });
diff --git a/lib/v2/sdu/maintainer.js b/lib/v2/sdu/maintainer.js
index db0b8798d..901e76c75 100644
--- a/lib/v2/sdu/maintainer.js
+++ b/lib/v2/sdu/maintainer.js
@@ -5,4 +5,5 @@ module.exports = {
'/mech/:type?': ['Ji4n1ng'],
'/sc/:type?': ['Ji4n1ng'],
'/wh/news/:column?': ['kxxt'],
+ '/wh/jwc/:column?': ['kxxt'],
};
diff --git a/lib/v2/sdu/radar.js b/lib/v2/sdu/radar.js
index 0056e5ef4..f43ea24c2 100644
--- a/lib/v2/sdu/radar.js
+++ b/lib/v2/sdu/radar.js
@@ -9,6 +9,12 @@ module.exports = {
source: wh.news.source,
target: '/sdu/wh' + wh.news.getTarget(value.url),
})),
+ 'jwc.wh': Object.entries(wh.jwc.columns).map(([, value]) => ({
+ title: wh.jwc.titlePrefix + value.name,
+ docs: wh.jwc.docs,
+ source: wh.jwc.source,
+ target: '/sdu/wh' + wh.jwc.getTarget(value.url),
+ })),
'www.cmse': [
{
title: '材料科学与工程学院通知',
diff --git a/lib/v2/sdu/router.js b/lib/v2/sdu/router.js
index 6913d656c..a60440332 100644
--- a/lib/v2/sdu/router.js
+++ b/lib/v2/sdu/router.js
@@ -5,4 +5,5 @@ module.exports = function (router) {
router.get('/mech/:type?', require('./mech'));
router.get('/sc/:type?', require('./sc'));
router.get('/wh/news/:column?', require('./wh/news'));
+ router.get('/wh/jwc/:column?', require('./wh/jwc'));
};
diff --git a/lib/v2/sdu/wh/jwc.js b/lib/v2/sdu/wh/jwc.js
new file mode 100644
index 000000000..be17c0296
--- /dev/null
+++ b/lib/v2/sdu/wh/jwc.js
@@ -0,0 +1,42 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const data = require('../data').wh.jwc;
+const extractor = require('../extractor');
+const { parseDate } = require('@/utils/parse-date');
+const timezone = require('@/utils/timezone');
+
+module.exports = async (ctx) => {
+ const column = ctx.params.column ?? 'gztz';
+ const baseUrl = data.url;
+ const response = await got(baseUrl + data.columns[column].url);
+ const $ = cheerio.load(response.data);
+ const items = $('.articleul li');
+ const out = await Promise.all(
+ items.map(async (index, item) => {
+ item = $(item);
+ const anchor = item.find('a');
+ const dateElement = item.find('div:last-of-type');
+ const dateText = dateElement.text();
+ dateElement.remove();
+ const href = anchor.attr('href');
+ const link = href.startsWith('http') ? href : baseUrl + href;
+ const title = item.text();
+ const { description, author: exactAuthor, exactDate } = await ctx.cache.tryGet(link, async () => await extractor(link, ctx));
+ const author = exactAuthor ?? '教务处';
+ const pubDate = exactDate ?? timezone(parseDate(dateText.slice(1, dateText.length - 1), 'YYYY-MM-DD'), +8);
+ return {
+ title,
+ link,
+ description,
+ pubDate,
+ author,
+ };
+ })
+ );
+
+ ctx.state.data = {
+ title: `${data.name} ${data.columns[column].name}`,
+ link: baseUrl + data.columns[column].url,
+ item: out,
+ };
+};