From 53a95bfdf26a52222f4173f9d411a2d36c2f4d20 Mon Sep 17 00:00:00 2001 From: kyuuseiryuu Date: Wed, 25 Mar 2026 00:05:06 +0900 Subject: [PATCH] feat(kaiqiu): add match nums and view count with Redis caching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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. --- src/services/KaiqiuService.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/services/KaiqiuService.ts b/src/services/KaiqiuService.ts index b75c412..046308b 100644 --- a/src/services/KaiqiuService.ts +++ b/src/services/KaiqiuService.ts @@ -91,10 +91,12 @@ export class KaiqiuService { isFinished, isProcessing, location, + nums, + see, } = await this.getEventInfo(matchId); const event: IEventInfo = { title, - info: [`比赛时间:${startDate}`, place], + info: [`比赛时间:${startDate}`, place, see, nums], url: eventURL, startDate, matchId, @@ -128,14 +130,21 @@ export class KaiqiuService { public static async getEventInfo(eventId: string, force?: boolean) { // 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 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 eventContent = $('.event_content').text().replace(/(\r|\n)/g, ',').split(',').filter(Boolean).join(' '); const { y, M, D, H, m} = /比赛开始:.*?(?\d{4})年(?\d{2})月(?\d{2})日 \w+ (?\d{2}):(?\d{2})/ .exec(eventContent)?.groups ?? {}; const startDate = y ? `${y}-${M}-${D} ${H}:${m}` : ''; 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 = /(?\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') .text().split(' ')?.[1]?.trim() ?? ''; const startTime = dayjs.tz(startDate, 'Asia/Tokyo'); @@ -151,6 +160,8 @@ export class KaiqiuService { isProcessing, isFinished, location, + nums, + see: see ? `${see} 次查看` : '', } }