feat(kaiqiu): add match nums and view count with Redis caching
- Extract 'nums' (号码) and 'see' (查看次数) from event page content.
- Include extracted data in the `IEventInfo` structure for display.
- Implement Redis caching for event details (key: `my-kaiqiuwang:event-info:${eventId}`).
- Cache strategy: Store result for 60 seconds, or refresh if cached data shows timeout errors or force flag is set.
- Reduces redundant external requests and improves response reliability.
This commit is contained in:
parent
2bcf7eb8d8
commit
53a95bfdf2
@ -91,10 +91,12 @@ export class KaiqiuService {
|
|||||||
isFinished,
|
isFinished,
|
||||||
isProcessing,
|
isProcessing,
|
||||||
location,
|
location,
|
||||||
|
nums,
|
||||||
|
see,
|
||||||
} = await this.getEventInfo(matchId);
|
} = await this.getEventInfo(matchId);
|
||||||
const event: IEventInfo = {
|
const event: IEventInfo = {
|
||||||
title,
|
title,
|
||||||
info: [`比赛时间:${startDate}`, place],
|
info: [`比赛时间:${startDate}`, place, see, nums],
|
||||||
url: eventURL,
|
url: eventURL,
|
||||||
startDate,
|
startDate,
|
||||||
matchId,
|
matchId,
|
||||||
@ -128,14 +130,21 @@ export class KaiqiuService {
|
|||||||
|
|
||||||
public static async getEventInfo(eventId: string, force?: boolean) {
|
public static async getEventInfo(eventId: string, force?: boolean) {
|
||||||
// https://kaiqiuwang.cc/home/space-event-id-175775.html
|
// https://kaiqiuwang.cc/home/space-event-id-175775.html
|
||||||
|
const key = `my-kaiqiuwang:event-info:${eventId}`;
|
||||||
const eventURL = `${this.#baseURL}/home/space-event-id-${eventId}.html`;
|
const eventURL = `${this.#baseURL}/home/space-event-id-${eventId}.html`;
|
||||||
const eventPage = await fetch(eventURL, { headers: htmlRequestHeaders }).then(res => res.text() ?? '');
|
let eventPage = await redis.get(key) ?? '';
|
||||||
|
if (!eventPage || eventPage.includes('连接超时') || force) {
|
||||||
|
eventPage = await fetch(eventURL, { headers: htmlRequestHeaders }).then(res => res.text() ?? '');
|
||||||
|
await redis.setex(key, 60 * 1, eventPage);
|
||||||
|
}
|
||||||
const $ = cheerio.load(eventPage);
|
const $ = cheerio.load(eventPage);
|
||||||
const eventContent = $('.event_content').text().replace(/(\r|\n)/g, ',').split(',').filter(Boolean).join(' ');
|
const eventContent = $('.event_content').text().replace(/(\r|\n)/g, ',').split(',').filter(Boolean).join(' ');
|
||||||
const { y, M, D, H, m} = /比赛开始:.*?(?<y>\d{4})年(?<M>\d{2})月(?<D>\d{2})日 \w+ (?<H>\d{2}):(?<m>\d{2})/
|
const { y, M, D, H, m} = /比赛开始:.*?(?<y>\d{4})年(?<M>\d{2})月(?<D>\d{2})日 \w+ (?<H>\d{2}):(?<m>\d{2})/
|
||||||
.exec(eventContent)?.groups ?? {};
|
.exec(eventContent)?.groups ?? {};
|
||||||
const startDate = y ? `${y}-${M}-${D} ${H}:${m}` : '';
|
const startDate = y ? `${y}-${M}-${D} ${H}:${m}` : '';
|
||||||
const title = $('#mainarea > h2 > a:nth-child(3)').text().trim();
|
const title = $('#mainarea > h2 > a:nth-child(3)').text().trim();
|
||||||
|
const nums = $('#content > div:nth-child(1) > div > div.event_content > ul > li:nth-child(2)').text();
|
||||||
|
const see = /(?<see>\d+)\b/.exec($('#content > div:nth-child(1) > div > div.event_content > ul > li:nth-child(1)').text())?.groups?.see ?? '';
|
||||||
const location = $('#content > div:nth-child(1) > div > div.event_content > dl > dd:nth-child(6) > a')
|
const location = $('#content > div:nth-child(1) > div > div.event_content > dl > dd:nth-child(6) > a')
|
||||||
.text().split(' ')?.[1]?.trim() ?? '';
|
.text().split(' ')?.[1]?.trim() ?? '';
|
||||||
const startTime = dayjs.tz(startDate, 'Asia/Tokyo');
|
const startTime = dayjs.tz(startDate, 'Asia/Tokyo');
|
||||||
@ -151,6 +160,8 @@ export class KaiqiuService {
|
|||||||
isProcessing,
|
isProcessing,
|
||||||
isFinished,
|
isFinished,
|
||||||
location,
|
location,
|
||||||
|
nums,
|
||||||
|
see: see ? `${see} 次查看` : '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user