diff --git a/lib/routes/zsxq/types.ts b/lib/routes/zsxq/types.ts index 2d1178549c1e..19d5b8ea17b7 100644 --- a/lib/routes/zsxq/types.ts +++ b/lib/routes/zsxq/types.ts @@ -11,7 +11,7 @@ interface BasicTopic { create_time: string; digested: boolean; group: { - group_id: number; + group_id: number | string; name: string; type: string; background_url: string; @@ -22,14 +22,14 @@ interface BasicTopic { avatar_url: string; name: string; number: number; - user_id: number; + user_id: number | string; }; }>; likes_count: number; readers_count: number; reading_count: number; rewards_count: number; - topic_id: number; + topic_id: number | string; type: string; user_specific: { liked: false; diff --git a/lib/routes/zsxq/utils.ts b/lib/routes/zsxq/utils.ts index 00e08fcf5fb2..e2f8f25af32f 100644 --- a/lib/routes/zsxq/utils.ts +++ b/lib/routes/zsxq/utils.ts @@ -12,8 +12,12 @@ export async function customFetch>(path: s headers: { cookie: `zsxq_access_token=${config.zsxq.accessToken};`, }, + responseType: 'text', }); - const { succeeded, code, resp_data } = response.data as T; + // Preserve large integer IDs (topic_id, group_id, user_id etc.) by converting them to strings + // before JSON.parse, which would otherwise lose precision on numbers > Number.MAX_SAFE_INTEGER + const safeBody = (response.body as string).replaceAll(/("(?:topic_id|group_id|user_id|task_id|image_id|category_id)"\s*:\s*)(\d+)/g, '$1"$2"'); + const { succeeded, code, resp_data } = JSON.parse(safeBody) as T; if (succeeded) { return resp_data; } @@ -39,7 +43,7 @@ export function generateTopicDataItem(topics: Topic[]): DataItem[] { return topics.map((topic) => { let description: string | undefined; let title = ''; - const url = `https://wx.zsxq.com/topic/${topic.topic_id}`; + const url = `https://wx.zsxq.com/group/${topic.group.group_id}/topic/${topic.topic_id}`; switch (topic.type) { case 'talk': title = topic.talk?.text?.split('\n')[0] ?? '文章';