From 8ea8033e9b33deaba35f3b3ba055157a6181ea6c Mon Sep 17 00:00:00 2001
From: Fatpandac <1779196284@qq.com>
Date: Wed, 9 Feb 2022 21:00:18 +0800
Subject: [PATCH] =?UTF-8?q?feat(route):=20add=2012306=E7=81=AB=E8=BD=A6?=
=?UTF-8?q?=E7=A5=A8=E6=B6=88=E6=81=AF=20and=20refactor=20to=20V2=20(#9031?=
=?UTF-8?q?)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat(route): add 12306火车票消息 and refactor to V2
* fix(route): change guid
* fix(route): change to use RSSHub's default UA
* fix(route): add handle exception
---
docs/travel.md | 4 ++
lib/router.js | 3 -
lib/v2/12306/index.js | 108 +++++++++++++++++++++++++++++++
lib/v2/12306/maintainer.js | 4 ++
lib/v2/12306/radar.js | 28 ++++++++
lib/v2/12306/router.js | 4 ++
lib/v2/12306/templates/train.art | 31 +++++++++
lib/{routes => v2}/12306/zxdt.js | 0
8 files changed, 179 insertions(+), 3 deletions(-)
create mode 100644 lib/v2/12306/index.js
create mode 100644 lib/v2/12306/maintainer.js
create mode 100644 lib/v2/12306/radar.js
create mode 100644 lib/v2/12306/router.js
create mode 100644 lib/v2/12306/templates/train.art
rename lib/{routes => v2}/12306/zxdt.js (100%)
diff --git a/docs/travel.md b/docs/travel.md
index d49fb611c9..47ae09ac61 100644
--- a/docs/travel.md
+++ b/docs/travel.md
@@ -10,6 +10,10 @@ pageClass: routes
+### 售票信息
+
+
+
## All the Flight Deals
### 特价机票
diff --git a/lib/router.js b/lib/router.js
index 7060899bcd..c6068343e4 100644
--- a/lib/router.js
+++ b/lib/router.js
@@ -1422,9 +1422,6 @@ router.get('/ui-cn/user/:id', lazyloadRouteHandler('./routes/ui-cn/user'));
// Dcard
router.get('/dcard/:section/:type?', lazyloadRouteHandler('./routes/dcard/section'));
-// 12306
-router.get('/12306/zxdt/:id?', lazyloadRouteHandler('./routes/12306/zxdt'));
-
// 北京天文馆每日一图
router.get('/bjp/apod', lazyloadRouteHandler('./routes/bjp/apod'));
diff --git a/lib/v2/12306/index.js b/lib/v2/12306/index.js
new file mode 100644
index 0000000000..84e0f53b34
--- /dev/null
+++ b/lib/v2/12306/index.js
@@ -0,0 +1,108 @@
+const got = require('@/utils/got');
+const { art } = require('@/utils/render');
+const path = require('path');
+const config = require('@/config').value;
+
+const rootUrl = 'https://kyfw.12306.cn';
+
+async function getJSESSIONID(linkUrl) {
+ const res = await got({
+ method: 'get',
+ url: linkUrl,
+ headers: {
+ UserAgent: config.ua,
+ Referer: 'https://www.12306.cn/index/index.html',
+ },
+ });
+
+ return res.headers['set-cookie'].join().match(/JSESSIONID=([^;]+);/)[0];
+}
+
+function getStationInfo(stationName, ctx) {
+ return ctx.cache.tryGet(stationName, async () => {
+ const res = await got({
+ method: 'get',
+ url: `${rootUrl}/otn/resources/js/framework/station_name.js`,
+ headers: {
+ UserAgent: config.ua,
+ Referer: 'https://kyfw.12306.cn/otn/leftTicket/init',
+ },
+ });
+
+ return res.data
+ .split('@')
+ .map((item) => {
+ const itemData = item.split('|');
+
+ return itemData.indexOf(stationName) !== -1
+ ? {
+ code: itemData[2],
+ name: itemData[1],
+ }
+ : null;
+ })
+ .filter((item) => item)[0];
+ });
+}
+
+module.exports = async (ctx) => {
+ const date = ctx.params.date;
+ const fromStationInfo = await getStationInfo(ctx.params.from, ctx);
+ const toStationInfo = await getStationInfo(ctx.params.to, ctx);
+ const type = ctx.params.type ?? 'ADULT';
+
+ const apiUrl = `${rootUrl}/otn/leftTicket/queryA?leftTicketDTO.train_date=${date}&leftTicketDTO.from_station=${fromStationInfo.code}&leftTicketDTO.to_station=${toStationInfo.code}&purpose_codes=${type}`;
+ const linkUrl = `${rootUrl}/otn/leftTicket/init?linktypeid=dc&fs=${fromStationInfo.code}&ts=${toStationInfo.code}&date=${date}&flag=N,N,Y`;
+
+ const response = await got.get(apiUrl, {
+ headers: {
+ UserAgent: config.ua,
+ Referer: 'https://kyfw.12306.cn/otn/leftTicket/init',
+ Cookie: await getJSESSIONID(linkUrl),
+ },
+ });
+ const data = response.data.data.result;
+ const map = response.data.data.map;
+ if (data.length === 0) {
+ throw '没有找到相关车次,请检查参数是否正确';
+ }
+
+ const items = data.map((item) => {
+ const itemData = item.split('|');
+ const trainInfo = {
+ trainNo: itemData[3],
+ fromStation: map[itemData[6]],
+ toStation: map[itemData[7]],
+ startTime: itemData[8],
+ arriveTime: itemData[9],
+ duration: itemData[10],
+ today: itemData[11],
+ A9: itemData[32],
+ M: itemData[31],
+ O: itemData[30],
+ A6: itemData[29],
+ A4: itemData[28],
+ F: itemData[27],
+ A3: itemData[26],
+ A2: itemData[25],
+ A1: itemData[24],
+ WZ: itemData[23],
+ QT: itemData[22],
+ };
+
+ return {
+ title: `${trainInfo.fromStation} → ${trainInfo.toStation} ${trainInfo.startTime} ${trainInfo.arriveTime}`,
+ description: art(path.join(__dirname, 'templates/train.art'), {
+ trainInfo,
+ }),
+ link: linkUrl,
+ guid: item,
+ };
+ });
+
+ ctx.state.data = {
+ title: `${fromStationInfo.name} → ${toStationInfo.name} ${date}`,
+ link: linkUrl,
+ item: items,
+ };
+};
diff --git a/lib/v2/12306/maintainer.js b/lib/v2/12306/maintainer.js
new file mode 100644
index 0000000000..bca746f4fd
--- /dev/null
+++ b/lib/v2/12306/maintainer.js
@@ -0,0 +1,4 @@
+module.exports = {
+ '/:date/:from/:to/:type?': ['Fatpandac'],
+ '/zxdt/:id?': ['LogicJake'],
+};
diff --git a/lib/v2/12306/radar.js b/lib/v2/12306/radar.js
new file mode 100644
index 0000000000..3675c84d61
--- /dev/null
+++ b/lib/v2/12306/radar.js
@@ -0,0 +1,28 @@
+module.exports = {
+ '12306.cn': {
+ _name: '12306',
+ kyfw: [
+ {
+ title: '售票信息',
+ docs: 'https://docs.rsshub.app/travel.html#_12306-shou-shu-piao-piao-xin-shen-xi',
+ source: ['/', '/otn/leftTicket/init'],
+ target: (params, url) => {
+ const searchParams = new URL(url).searchParams;
+ const from = searchParams.get('fs').split(',')[0];
+ const to = searchParams.get('ts').split(',')[0];
+ const date = searchParams.get('date');
+
+ return `/12306/${date}/${from}/${to}`;
+ },
+ },
+ ],
+ www: [
+ {
+ title: '最新动态',
+ docs: 'https://docs.rsshub.app/travel.html#_12306-zui-cuo-xin-dong-tai',
+ source: ['/', '/mormhweb/1/:id/index_fl.html'],
+ target: '/12306/zxdt/:id',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/12306/router.js b/lib/v2/12306/router.js
new file mode 100644
index 0000000000..f454271a94
--- /dev/null
+++ b/lib/v2/12306/router.js
@@ -0,0 +1,4 @@
+module.exports = function (router) {
+ router.get('/:date/:from/:to/:type?', require('./index'));
+ router.get('/zxdt/:id?', require('./zxdt'));
+};
diff --git a/lib/v2/12306/templates/train.art b/lib/v2/12306/templates/train.art
new file mode 100644
index 0000000000..ea1522ff96
--- /dev/null
+++ b/lib/v2/12306/templates/train.art
@@ -0,0 +1,31 @@
+车次:{{ trainInfo.trainNo}}
+
+始发站:{{ trainInfo.fromStation}} → {{ trainInfo.toStation}}
+
+出发时间:{{ trainInfo.startTime}}
+
+到达时间:{{ trainInfo.arriveTime}}
+
+历时:{{ trainInfo.duration}} {{ trainInfo.today === 'N' ? '次日达' : '' }}
+
+商务座/特等座:{{ trainInfo.A9 ? trainInfo.A9 : '无' }}
+
+一等座:{{ trainInfo.M ? trainInfo.M : '无' }}
+
+二等座/二等包座:{{ trainInfo.O ? trainInfo.O : '无' }}
+
+高级软卧:{{ trainInfo.A6 ? trainInfo.A6 : '无' }}
+
+软卧/一等卧:{{ trainInfo.A4 ? trainInfo.A4 : '无' }}
+
+动卧:{{ trainInfo.F ? trainInfo.F : '无' }}
+
+硬卧/二等卧:{{ trainInfo.A3 ? trainInfo.A3 : '无' }}
+
+软座: {{ trainInfo.A2 ? trainInfo.A2 : '无' }}
+
+硬座: {{ trainInfo.A1 ? trainInfo.A1 : '无' }}
+
+无座: {{ trainInfo.WZ ? trainInfo.WZ : '无' }}
+
+其他: {{ trainInfo.QT ? trainInfo.QT : '无' }}
diff --git a/lib/routes/12306/zxdt.js b/lib/v2/12306/zxdt.js
similarity index 100%
rename from lib/routes/12306/zxdt.js
rename to lib/v2/12306/zxdt.js