Uh oh! 看来你迷路了。
请点击按钮返回首页!
├── .gitignore ├── 404.html ├── Ads.txt ├── LICENSE ├── README.md ├── api ├── about.js ├── guzhi.js ├── practice.js └── shields.js ├── baidu_verify_code-5Upmgof2g6.html ├── favicon.png ├── index ├── bg.jpg └── index.html ├── package-lock.json ├── package.json ├── sitemap.xml ├── src ├── about-card.js ├── common.js ├── guzhi-card.js ├── practice-card.js └── shields.js ├── test └── test-function.js ├── vercel.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | test.svg 3 | node_modules 4 | .vercel 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |2 |
🏆 优雅的洛谷用户信息卡片及生成工具
4 | 5 | 6 | 10 | 11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
如果这个项目对您有帮助,请考虑给它一个 Star ⭐
188 | -------------------------------------------------------------------------------- /api/about.js: -------------------------------------------------------------------------------- 1 | const { fetchAbout, renderSVG } = require("../src/about-card.js"); 2 | const { renderError } = require("../src/common.js") 3 | 4 | module.exports = async (req, res) => { 5 | const { 6 | id, 7 | hide_title, 8 | dark_mode, 9 | disable_cache, 10 | card_width = 500, 11 | } = req.query; 12 | 13 | res.setHeader("Content-Type", "image/svg+xml"); 14 | if (!disable_cache) { 15 | res.setHeader("Cache-Control", "public, max-age=43200"); // 43200s(12h) cache 16 | } 17 | 18 | const validId = /^[1-9]\d*$/; 19 | const clamp = (min, max, n) => Math.max(min, Math.min(max, n)); 20 | 21 | if (!validId.test(id)) { 22 | return res.send(renderError(`"${id}"不是一个合法uid`, { darkMode: dark_mode })); 23 | } 24 | if (!validId.test(card_width)) { 25 | return res.send(renderError(`卡片宽度"${card_width}"不合法`, { darkMode: dark_mode })); 26 | } 27 | 28 | const about = await fetchAbout(id); 29 | return res.send(renderSVG(about, { 30 | hideTitle: hide_title, 31 | darkMode: dark_mode, 32 | cardWidth: clamp(500, 1920, card_width), 33 | })); 34 | }; 35 | -------------------------------------------------------------------------------- /api/guzhi.js: -------------------------------------------------------------------------------- 1 | const { renderGuzhiCard } = require("../src/guzhi-card.js"); 2 | const { fetchAbout } = require("../src/about-card.js"); 3 | const { renderError } = require("../src/common.js") 4 | const axios = require("axios"); 5 | 6 | async function fetchGuzhi(id, ranking) { 7 | var page = Math.floor((ranking - 1) / 50) + 1; 8 | 9 | const res = await axios.get(`https://www.luogu.com.cn/ranking?page=${page}&_contentOnly`); 10 | 11 | if (res.data.code != 200) { 12 | return "Not found."; 13 | } 14 | 15 | const rankList = res.data.currentData.rankList.result; 16 | 17 | for (var index = 0; index < 50; index++) { 18 | if (!rankList[index]) { 19 | continue; 20 | } 21 | if (rankList[index].user.uid == id) { 22 | return `${rankList[index].basicRating},${rankList[index].practiceRating},${rankList[index].socialRating},${rankList[index].contestRating},${rankList[index].prizeRating}`; 23 | } 24 | } 25 | return `Not found.`; 26 | } 27 | 28 | module.exports = async (req, res) => { 29 | const { id, scores, hide_title, dark_mode, disable_cache, card_width = 500 } = req.query; 30 | var finally_scores 31 | 32 | res.setHeader("Content-Type", "image/svg+xml"); 33 | if (!disable_cache) { 34 | res.setHeader("Cache-Control", "public, max-age=43200"); // 43200s(12h) cache 35 | } 36 | 37 | const regNum = /^[1-9]\d*$/; 38 | const clamp = (min, max, n) => Math.max(min, Math.min(max, n)); 39 | 40 | if (!regNum.test(card_width)) { 41 | return res.send( 42 | renderError(`卡片宽度"${card_width}"不合法`, { darkMode: dark_mode }) 43 | ); 44 | } 45 | if (id != undefined && !regNum.test(id)) { 46 | return res.send(renderError(`"${id}"不是一个合法uid`, { darkMode: dark_mode })); 47 | } 48 | 49 | let about = null; 50 | 51 | if (id != undefined) { 52 | about = await fetchAbout(id); 53 | } 54 | 55 | if (about.ranking >= 1 && about.ranking <= 1000) { 56 | finally_scores = await fetchGuzhi(id, about.ranking); 57 | if (finally_scores == "Not found.") { 58 | finally_scores = scores; 59 | } 60 | } 61 | else { 62 | finally_scores = scores; 63 | } 64 | 65 | return res.send( 66 | renderGuzhiCard(about, finally_scores, { 67 | hideTitle: about === null ? true : hide_title, 68 | darkMode: dark_mode, 69 | cardWidth: clamp(500, 1920, card_width), 70 | }) 71 | ); 72 | }; 73 | -------------------------------------------------------------------------------- /api/practice.js: -------------------------------------------------------------------------------- 1 | const { fetchStats, renderSVG } = require("../src/practice-card.js"); 2 | const { renderError } = require("../src/common.js") 3 | 4 | module.exports = async (req, res) => { 5 | const { 6 | id, 7 | hide_title, 8 | dark_mode, 9 | disable_cache, 10 | card_width = 500, 11 | } = req.query; 12 | 13 | res.setHeader("Content-Type", "image/svg+xml"); 14 | if (!disable_cache) { 15 | res.setHeader("Cache-Control", "public, max-age=43200"); // 43200s(12h) cache 16 | } 17 | 18 | const validId = /^[1-9]\d*$/; 19 | const clamp = (min, max, n) => Math.max(min, Math.min(max, n)); 20 | 21 | if (!validId.test(id)) { 22 | return res.send(renderError(`"${id}"不是一个合法uid`, { darkMode: dark_mode })); 23 | } 24 | if (!validId.test(card_width)) { 25 | return res.send(renderError(`卡片宽度"${card_width}"不合法`, { darkMode: dark_mode })); 26 | } 27 | 28 | const stats = await fetchStats(id); 29 | return res.send(renderSVG(stats, { 30 | hideTitle: hide_title, 31 | darkMode: dark_mode, 32 | cardWidth: clamp(500, 1920, card_width), 33 | })); 34 | }; 35 | -------------------------------------------------------------------------------- /api/shields.js: -------------------------------------------------------------------------------- 1 | const { fetchStats } = require("../src/practice-card.js"); 2 | const { renderSVG } = require("../src/shields.js"); 3 | const { renderError } = require("../src/common.js"); 4 | 5 | module.exports = async (req, res) => { 6 | const { id } = req.query; 7 | 8 | res.setHeader("Content-Type", "image/svg+xml"); 9 | res.setHeader("Cache-Control", "public, max-age=43200"); // 43200s(12h) cache 10 | 11 | const validId = /^[1-9]\d*$/; 12 | 13 | if (!validId.test(id)) { 14 | return res.send(renderError(`"${id}"不是一个合法uid`)); 15 | } 16 | 17 | const stats = await fetchStats(id); 18 | return res.send(renderSVG(stats)); 19 | }; -------------------------------------------------------------------------------- /baidu_verify_code-5Upmgof2g6.html: -------------------------------------------------------------------------------- 1 | da3671a64b19fe84a3b1aa064a9ce0e1 -------------------------------------------------------------------------------- /favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YangguangZhou/Luogu-User-Card/05a621f59f816a8cf41ee3b04c0054a8c0ab6bda/favicon.png -------------------------------------------------------------------------------- /index/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YangguangZhou/Luogu-User-Card/05a621f59f816a8cf41ee3b04c0054a8c0ab6bda/index/bg.jpg -------------------------------------------------------------------------------- /index/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |458 | Luogu-User-Card是一个动态生成洛谷用户数据卡片的工具,可以展示用户的基本信息、做题情况、咕值信息等,可以插入到个人主页、博客、GitHub等支持插入图片的地方。 459 |
460 | 461 |详细展示用户的做题情况
476 |显示用户类型、关注、咕值排名、个性签名
481 |展示用户的咕值详情
486 |简洁显示用户做题数据
491 |将上方生成的链接复制到任意支持插入图片的地方即可使用。
601 |如果要在 Markdown 中使用,可以使用以下格式:
602 |如果需要添加点击跳转,可以使用以下格式:
604 |