diff --git a/README.md b/README.md index 03940826..5d225cd2 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ | 今日头条 | 热榜 | toutiao | 🟢 | | 36 氪 | 热榜 | 36kr | 🟢 | | 51CTO | 推荐榜 | 51cto | 🟢 | +| CSDN | 排行榜 | csdn | 🟢 | | 稀土掘金 | 热榜 | juejin | 🟢 | | 腾讯新闻 | 热点榜 | qq-news | 🟢 | | 网易新闻 | 热点榜 | netease-news | 🟢 | diff --git a/src/router.types.d.ts b/src/router.types.d.ts index 82885d72..5c99f6f0 100644 --- a/src/router.types.d.ts +++ b/src/router.types.d.ts @@ -260,4 +260,13 @@ export type RouterType = { comment_count: number; created_at: number; }; + csdn: { + nickName: string; + articleTitle: string; + articleDetailUrl: string; + picList: [string]; + hotRankScore: string; + period: string; + productId: string; + }; }; diff --git a/src/routes/csdn.ts b/src/routes/csdn.ts new file mode 100644 index 00000000..0874d6db --- /dev/null +++ b/src/routes/csdn.ts @@ -0,0 +1,41 @@ +import type { RouterData } from "../types.js"; +import type { RouterType } from "../router.types.js"; +import { get } from "../utils/getData.js"; +import { getTime } from "../utils/getTime.js"; + +export const handleRoute = async (_: undefined, noCache: boolean) => { + const { fromCache, data, updateTime } = await getList(noCache); + const routeData: RouterData = { + name: "csdn", + title: "CSDN", + type: "排行榜", + description: "专业开发者社区", + link: "https://www.csdn.net/", + total: data?.length || 0, + updateTime, + fromCache, + data, + }; + return routeData; +}; + +const getList = async (noCache: boolean) => { + const url = "https://blog.csdn.net/phoenix/web/blog/hot-rank?page=0&pageSize=30"; + const result = await get({ url, noCache }); + const list = result.data.data; + return { + fromCache: result.fromCache, + updateTime: result.updateTime, + data: list.map((v: RouterType["csdn"]) => ({ + id: v.productId, + title: v.articleTitle, + cover: v.picList?.[0] || null, + desc: null, + author: v.nickName, + timestamp: getTime(v.period), + hot: Number(v.hotRankScore), + url: v.articleDetailUrl, + mobileUrl: v.articleDetailUrl, + })), + }; +}; diff --git a/src/utils/getTime.ts b/src/utils/getTime.ts index 0d66984d..1df59c4e 100644 --- a/src/utils/getTime.ts +++ b/src/utils/getTime.ts @@ -8,22 +8,54 @@ interface CurrentDateTime { minute: number; second: number; } -export const getTime = (timeInput: string | number): number => { +export const getTime = (timeInput: string | number): number | null => { try { - let num: number | string; - // 尝试将输入转换为数字 + let num: number; + + // 处理字符串的情况 if (typeof timeInput === "string") { + // 尝试将字符串直接转换为数字 num = Number(timeInput); - // 检查转换结果是否为有效数字 + if (isNaN(num)) { - // 处理为字符串的日期时间 - return dayjs(timeInput).valueOf(); + // 将各种分隔符替换为标准格式 + let standardizedInput = timeInput + .replace(/(\d{4})-(\d{2})-(\d{2})-(\d{2})/, "$1-$2-$3 $4") // "YYYY-MM-DD-HH" -> "YYYY-MM-DD HH" + .replace(/(\d{4})-(\d{2})-(\d{2})[T\s](\d{2}):?(\d{2})?:?(\d{2})?/, "$1-$2-$3 $4:$5:$6") // "YYYY-MM-DDTHH:mm:ss" -> "YYYY-MM-DD HH:mm:ss" + .replace(/(\d{4})[-/](\d{2})[-/](\d{2})/, "$1-$2-$3"); // "YYYY/MM/DD" or "YYYY-MM-DD" -> "YYYY-MM-DD" + + // 减少解析过程中可能的多余空格 + standardizedInput = standardizedInput.replace(/\s+/, " ").trim(); + + // 处理标准化后的日期时间字符串 + const formatPatterns = [ + "YYYY-MM-DD HH:mm:ss", + "YYYY-MM-DD HH:mm", + "YYYY-MM-DD HH", + "YYYY-MM-DD", + ]; + + let parsedDate: dayjs.Dayjs | null = null; + for (const pattern of formatPatterns) { + parsedDate = dayjs(standardizedInput, pattern, true); + if (parsedDate.isValid()) { + break; + } + } + + if (parsedDate && parsedDate.isValid()) { + return parsedDate.valueOf(); + } else { + return null; + } } } else { num = timeInput; } + // 是否为毫秒级时间戳 if (num > 946684800000) { + // 以2000年作为毫秒时间戳参考点 return num; } else { return num * 1000;