diff --git a/lib/v2/showstart/artist.js b/lib/v2/showstart/artist.js
new file mode 100644
index 00000000000000..bb2e0d5d4e99ff
--- /dev/null
+++ b/lib/v2/showstart/artist.js
@@ -0,0 +1,15 @@
+const { TITLE, HOST } = require('./const');
+const { fetchPerformerInfo } = require('./service');
+
+module.exports = async (ctx) => {
+ const id = ctx.params.id;
+ const artist = await fetchPerformerInfo({
+ performerId: id,
+ });
+ ctx.state.data = {
+ title: `${TITLE} - ${artist.name}`,
+ description: artist.content,
+ link: `${HOST}/artist/${artist.id}`,
+ item: artist.activityList,
+ };
+};
diff --git a/lib/v2/showstart/brand.js b/lib/v2/showstart/brand.js
new file mode 100644
index 00000000000000..0b7fc4d8c43487
--- /dev/null
+++ b/lib/v2/showstart/brand.js
@@ -0,0 +1,15 @@
+const { TITLE, HOST } = require('./const');
+const { fetchBrandInfo } = require('./service');
+
+module.exports = async (ctx) => {
+ const id = ctx.params.id;
+ const brand = await fetchBrandInfo({
+ brandId: id,
+ });
+ ctx.state.data = {
+ title: `${TITLE} - ${brand.name}`,
+ description: brand.content,
+ link: `${HOST}/host/${brand.id}`,
+ item: brand.activityList,
+ };
+};
diff --git a/lib/v2/showstart/event.js b/lib/v2/showstart/event.js
index 38e6aafc15f692..080db7f8bb82cd 100644
--- a/lib/v2/showstart/event.js
+++ b/lib/v2/showstart/event.js
@@ -4,7 +4,7 @@ const { fetchActivityList, fetchDictionary } = require('./service');
module.exports = async (ctx) => {
const cityCode = parseInt(ctx.params.cityCode);
const showStyle = parseInt(ctx.params.showStyle);
- const { items } = await fetchActivityList({
+ const items = await fetchActivityList({
cityCode,
showStyle,
});
diff --git a/lib/v2/showstart/maintainer.js b/lib/v2/showstart/maintainer.js
index 1eea6511d8e381..6526631fcf6dd8 100644
--- a/lib/v2/showstart/maintainer.js
+++ b/lib/v2/showstart/maintainer.js
@@ -1,4 +1,6 @@
module.exports = {
+ '/artist/:id': ['lchtao26'],
+ '/brand/:id': ['lchtao26'],
'/event/:cityCode/:showStyle?': ['lchtao26'],
- '/search/:keyword': ['lchtao26'],
+ '/search/:type/:keyword?': ['lchtao26'],
};
diff --git a/lib/v2/showstart/params.js b/lib/v2/showstart/params.js
deleted file mode 100644
index 26a94d5da5becb..00000000000000
--- a/lib/v2/showstart/params.js
+++ /dev/null
@@ -1,22 +0,0 @@
-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;
- }
-};
diff --git a/lib/v2/showstart/radar.js b/lib/v2/showstart/radar.js
index 55548479980b24..51c6e4af0957c3 100644
--- a/lib/v2/showstart/radar.js
+++ b/lib/v2/showstart/radar.js
@@ -20,9 +20,21 @@ module.exports = {
target: (_, url) => {
const search = new URL(url).searchParams;
const keyword = search.get('keyword') || '';
- return `/showstart/search/${keyword}`;
+ return `/showstart/search/event/${keyword}`;
},
},
+ {
+ title: '音乐人 - 演出更新',
+ docs: 'https://docs.rsshub.app/routes/shopping#yin-yue-ren-yan-chu-geng-xin',
+ source: ['/artist/:id'],
+ target: '/showstart/artist/:id',
+ },
+ {
+ title: '厂牌 - 演出更新',
+ docs: 'https://docs.rsshub.app/routes/shopping#chang-pai-yan-chu-geng-xin',
+ source: ['/host/:id'],
+ target: '/showstart/brand/:id',
+ },
],
},
};
diff --git a/lib/v2/showstart/router.js b/lib/v2/showstart/router.js
index b4d932712082fa..8dd29cee311569 100644
--- a/lib/v2/showstart/router.js
+++ b/lib/v2/showstart/router.js
@@ -1,5 +1,6 @@
module.exports = (router) => {
+ router.get('/artist/:id', require('./artist'));
+ router.get('/brand/:id', require('./brand'));
router.get('/event/:cityCode/:showStyle?', require('./event'));
- router.get('/search/:keyword?', require('./search'));
- router.get('/params/:type', require('./params'));
+ router.get('/search/:type/:keyword?', require('./search'));
};
diff --git a/lib/v2/showstart/search.js b/lib/v2/showstart/search.js
index 3a9bddb58f8edc..cc222c1a25e62e 100644
--- a/lib/v2/showstart/search.js
+++ b/lib/v2/showstart/search.js
@@ -1,14 +1,51 @@
const { TITLE, HOST } = require('./const');
-const { fetchActivityList } = require('./service');
+const { fetchActivityList, fetchPerformerList, fetchBrandList, fetchCityList, fetchStyleList } = require('./service');
module.exports = async (ctx) => {
- const keyword = ctx.params.keyword;
- const { items } = await fetchActivityList({
- keyword,
- });
- ctx.state.data = {
- title: `${TITLE} - ${keyword}`,
- link: HOST,
- item: items,
- };
+ const type = ctx.params.type || '';
+ const keyword = ctx.params.keyword || '';
+
+ switch (type) {
+ case 'event':
+ ctx.state.data = {
+ title: `${TITLE} - 搜演出 - ${keyword || '全部'}`,
+ link: HOST,
+ item: await fetchActivityList({ keyword }),
+ };
+ break;
+ case 'artist':
+ ctx.state.data = {
+ title: `${TITLE} - 搜艺人 - ${keyword || '全部'}`,
+ link: HOST,
+ item: await fetchPerformerList({ searchKeyword: keyword }),
+ };
+ break;
+ case 'brand':
+ ctx.state.data = {
+ title: `${TITLE} - 搜厂牌 - ${keyword || '全部'}`,
+ link: HOST,
+ item: await fetchBrandList({ searchKeyword: keyword }),
+ };
+ break;
+ case 'city':
+ ctx.state.data = {
+ title: `${TITLE} - 搜城市 - ${keyword || '全部'}`,
+ link: HOST,
+ item: await fetchCityList(keyword),
+ };
+ break;
+ case 'style':
+ ctx.state.data = {
+ title: `${TITLE} - 搜风格 - ${keyword || '全部'}`,
+ link: HOST,
+ item: await fetchStyleList(keyword),
+ };
+ break;
+ default:
+ ctx.state.data = {
+ title: `${TITLE} - 搜演出 - ${type || '全部'}`,
+ link: HOST,
+ item: await fetchActivityList({ keyword: type }),
+ };
+ }
};
diff --git a/lib/v2/showstart/service.js b/lib/v2/showstart/service.js
index 2a0b53915bc02f..f5d1a67cc21e9c 100644
--- a/lib/v2/showstart/service.js
+++ b/lib/v2/showstart/service.js
@@ -25,49 +25,121 @@ async function fetchActivityList(
) {
const accessToken = await getAccessToken();
const resp = await post('/web/activity/list', accessToken, params);
+ return resp.result.result.map((item) => formatActivity(item));
+}
+function formatActivity(item) {
const image = (src) => (src ? `` : '');
const time = (time) => (time ? `
演出时间:${time}
` : ''); const address = (cityName, siteName) => (cityName || siteName ? `地址:${[cityName, siteName].join(' - ')}
` : ''); const performers = (name) => (name ? `艺人:${name}
` : ''); const price = (price) => (price ? `票价:${price}
` : ''); + return { + title: item.title, + link: `${HOST}/event/${item.id}`, + description: [image(item.poster), time(item.showTime), address(item.cityName, item.siteName), performers(item.performers), price(item.price)].join(''), + }; +} +async function fetchPerformerList( + params = { + pageNo: '1', + pageSize: '30', + searchKeyword: '', + styleId: '', + } +) { + const accessToken = await getAccessToken(); + const resp = await post('/web/performer/list', accessToken, params); + return resp.result.result.map((item) => ({ + title: item.name, + link: `${HOST}/artist/${item.id}`, + description: `id: ${item.id}`, + })); +} + +async function fetchPerformerInfo( + params = { + performerId: '', + } +) { + const accessToken = await getAccessToken(); + const resp = await post('/web/performer/info', accessToken, params); return { - items: resp.result.result.map((item) => ({ - title: item.title, - link: `${HOST}/event/${item.id}`, - description: [image(item.poster), time(item.showTime), address(item.cityName, item.siteName), performers(item.performers), price(item.price)].join(''), - })), + id: params.id, + name: resp.result.name, + content: resp.result.content, + avatar: resp.result.avatar, + poster: resp.result.poster, + styles: resp.result.styles, + activityList: resp.result.activities.map((item) => formatActivity(item)), }; } +async function fetchBrandInfo( + params = { + brandId: '', + } +) { + const accessToken = await getAccessToken(); + const resp = await post('/web/brand/info', accessToken, params); + return { + id: params.id, + name: resp.result.name, + content: resp.result.content, + avatar: resp.result.avatar, + poster: resp.result.poster, + activityList: resp.result.activities.map((item) => formatActivity(item)), + }; +} + +async function fetchBrandList( + params = { + pageNo: '1', + pageSize: '30', + searchKeyword: '', + } +) { + const accessToken = await getAccessToken(); + const resp = await post('/web/brand/list', accessToken, params); + return resp.result.result.map((item) => ({ + title: item.name, + link: `${HOST}/host/${item.id}`, + description: `id: ${item.id}`, + })); +} + async function fetchParams() { const accessToken = await getAccessToken(); return post('/web/activity/list/params', accessToken); } -async function fetchCityList() { +async function fetchCityList(keyword = '') { 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}`, - })); + return cities + .filter((item) => item.cityName.includes(keyword.trim())) + .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() { +async function fetchStyleList(keyword = '') { 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}`, - })); + return styles + .filter((item) => item.showName.includes(keyword.trim())) + .map((item) => ({ + title: item.showName, + link: `${HOST}/event/list?showStyle=${item.key}`, + description: `showStyle: ${item.key}`, + })); } async function fetchDictionary(cityCode, showStyle) { @@ -86,5 +158,9 @@ module.exports = { fetchActivityList, fetchCityList, fetchStyleList, + fetchPerformerList, + fetchPerformerInfo, + fetchBrandList, + fetchBrandInfo, fetchDictionary, }; diff --git a/website/docs/routes/shopping.mdx b/website/docs/routes/shopping.mdx index 0bbe35fc3e3f80..200bf94e3a9446 100644 --- a/website/docs/routes/shopping.mdx +++ b/website/docs/routes/shopping.mdx @@ -711,10 +711,9 @@ For instance, in `https://www.zagg.com/en_us/new-arrivals?brand=164&cat=3038%2C3 :::tip -路由参数查询 +- 演出城市 `cityCode` 查询: `/showstart/search/city/:keyword`, 如: https://rsshub.app/showstart/search/city/杭州 -- cityCode: https://rsshub.app/showstart/params/city -- showStyle: https://rsshub.app/showstart/params/style +- 演出风格 `showStyle` 查询: `/showstart/search/style/:keyword`,如: https://rsshub.app/showstart/search/style/摇滚 ::: @@ -722,6 +721,26 @@ For instance, in `https://www.zagg.com/en_us/new-arrivals?brand=164&cat=3038%2C3