feat(route/秀动网): add '/params' route for route params look up, add more detail into '/event' feed item description (#13879)

* change '/search/:keyword' to optional

* feat: add more info to description

* feat: add '/params/city' and '/params/style' for params look up

reason for adding this route:

it's hard to find route params in url, expecially in mobile mode, the
wap.showstasrt.com website url doesn't match the shows city and style

* chore: implement sortBy and uniqBy

* chore: move sortBy, uniqBy to utils
This commit is contained in:
lchtao26 2023-11-25 01:05:35 +08:00 committed by GitHub
parent 6c3eb6d0a8
commit bb589044a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 6 deletions

View File

@ -0,0 +1,22 @@
const { TITLE, HOST } = require('./const');
const { fetchCityList, fetchStyleList } = require('./service');
module.exports = async (ctx) => {
const type = ctx.params.type;
switch (type) {
case 'city':
ctx.state.data = {
title: `${TITLE} - 演出城市`,
link: `HOST`,
item: await fetchCityList(),
};
break;
case 'style':
ctx.state.data = {
title: `${TITLE} - 演出风格`,
link: HOST,
item: await fetchStyleList(),
};
break;
}
};

View File

@ -1,4 +1,5 @@
module.exports = (router) => {
router.get('/event/:cityCode/:showStyle?', require('./event'));
router.get('/search/:keyword', require('./search'));
router.get('/search/:keyword?', require('./search'));
router.get('/params/:type', require('./params'));
};

View File

@ -1,5 +1,5 @@
const { HOST } = require('./const');
const { getAccessToken, post } = require('./utils');
const { getAccessToken, post, sortBy, uniqBy } = require('./utils');
async function fetchActivityList(
params = {
@ -25,18 +25,53 @@ async function fetchActivityList(
) {
const accessToken = await getAccessToken();
const resp = await post('/web/activity/list', accessToken, params);
const image = (src) => (src ? `<img src="${src}" />` : '');
const time = (time) => (time ? `<p>演出时间:${time}</p>` : '');
const address = (cityName, siteName) => (cityName || siteName ? `<p>地址:${[cityName, siteName].join(' - ')}</p>` : '');
const performers = (name) => (name ? `<p>艺人:${name}</p>` : '');
const price = (price) => (price ? `<p>票价:${price}</p>` : '');
return {
items: resp.result.result.map((item) => ({
title: item.title,
link: `${HOST}/event/${item.id}`,
description: `地点:${item.cityName} | ${item.siteName}`,
description: [image(item.poster), time(item.showTime), address(item.cityName, item.siteName), performers(item.performers), price(item.price)].join(''),
})),
};
}
async function fetchDictionary(cityCode, showStyle) {
async function fetchParams() {
const accessToken = await getAccessToken();
const resp = await post('/web/activity/list/params', accessToken);
return post('/web/activity/list/params', accessToken);
}
async function fetchCityList() {
const resp = await fetchParams();
const cities = sortBy(resp.result, 'cityCode');
return cities.map((item) => ({
title: item.cityName,
link: `${HOST}/event/list?cityCode=${item.cityCode}`,
description: `cityCode: ${item.cityCode}`,
}));
}
// styles is embed in each city item
// so we need to fetch all city items and then extract styles from them
async function fetchStyleList() {
const resp = await fetchParams();
let styles = resp.result.flatMap((item) => item.styles);
styles = uniqBy(styles, 'key');
styles = sortBy(styles, 'key');
return styles.map((item) => ({
title: item.showName,
link: `${HOST}/event/list?showStyle=${item.key}`,
description: `showStyle: ${item.key}`,
}));
}
async function fetchDictionary(cityCode, showStyle) {
const resp = await fetchParams();
const target = resp.result.find((item) => item.cityCode === cityCode);
if (!target) {
return {};
@ -49,5 +84,7 @@ async function fetchDictionary(cityCode, showStyle) {
module.exports = {
fetchActivityList,
fetchCityList,
fetchStyleList,
fetchDictionary,
};

View File

@ -60,8 +60,33 @@ const post = async (requestPath, accessToken = md5(Date.now().toString()), paylo
return response;
};
function sortBy(items, key) {
return items.sort((a, b) => {
if (a[key] < b[key]) {
return -1;
}
if (a[key] > b[key]) {
return 1;
}
return 0;
});
}
function uniqBy(items, key) {
const set = new Set();
return items.filter((item) => {
if (set.has(item[key])) {
return false;
}
set.add(item[key]);
return true;
});
}
module.exports = {
post,
getAccessToken,
uuid,
sortBy,
uniqBy,
};

View File

@ -703,7 +703,14 @@ For instance, in `https://www.zagg.com/en_us/new-arrivals?brand=164&cat=3038%2C3
<Route author="lchtao26" example="/showstart/event/571/3" path="/showstart/event/:cityCode/:showStyle?" paramsDesc={['演出城市 (编号)', '演出风格 (编号)']}/>
相关路由参数可在 URL 中找到,如:`https://www.showstart.com/event/list?pageNo=1&pageSize=20&cityCode=571&showStyle=26`
:::tip
路由参数查询
- cityCode: https://rsshub.app/showstart/params/city
- showStyle: https://rsshub.app/showstart/params/style
:::
### 演出搜索 {#xiu-dong-wang-yan-chu-sou-suo}