refactor(api-docs): 重构 API 文档组件并优化构建 ID 生成逻辑
- 移除了公告功能,替换为固定公告内容 - 更新了站点信息,包括友情链接和邮箱地址 - 优化了图片总数和接口文档的展示方式 - 重新实现了构建 ID 生成逻辑,使用项目文件哈希值代替时间戳
This commit is contained in:
parent
c6818e848c
commit
36ef5db441
@ -20,27 +20,20 @@ import { ExternalLink, GitCommit } from "lucide-react";
|
||||
export default function ApiDocsComponent() {
|
||||
const [activePage, setActivePage] = useState("home");
|
||||
const [imageCount, setImageCount] = useState<number | null>(null);
|
||||
const [announcements, setAnnouncements] = useState<
|
||||
Array<{ date: string; content: string }>
|
||||
>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const [imageCountResponse, announcementsResponse] = await Promise.all([
|
||||
fetch("/?api=total-pic"),
|
||||
fetch("/?api=announcements"),
|
||||
const [imageCountResponse] = await Promise.all([
|
||||
fetch("/?api=total-pic")
|
||||
]);
|
||||
const imageCountData = await imageCountResponse.json();
|
||||
const announcementsData = await announcementsResponse.json();
|
||||
setImageCount(imageCountData.count);
|
||||
setAnnouncements(announcementsData.announcements);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch data:", error);
|
||||
setImageCount(null);
|
||||
setAnnouncements([]);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@ -119,7 +112,7 @@ export default function ApiDocsComponent() {
|
||||
];
|
||||
|
||||
const friendlyLinks = [
|
||||
{ name: "mei的网络日志", url: "https://mmeiblog.cn" }
|
||||
{ name: "mei的网络日志", url: "https://mei.lv" }
|
||||
];
|
||||
|
||||
const HomePage = () => (
|
||||
@ -144,16 +137,6 @@ export default function ApiDocsComponent() {
|
||||
<p className="mt-4 text-gray-600">
|
||||
用于实践我最新学到的技术,也能勉强保证服务可用性(但被打了可扛不住)。
|
||||
</p>
|
||||
<p className="mt-4 text-gray-600">
|
||||
如果你觉得这个API有什么不完善的地方或者说你有什么更好的想♂法,可以发送邮箱至{" "}
|
||||
<a
|
||||
href="mailto:i@mmeiblog.cn"
|
||||
className="text-blue-600 hover:underline"
|
||||
>
|
||||
i@mmeiblog.cn
|
||||
</a>
|
||||
。
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -162,26 +145,17 @@ export default function ApiDocsComponent() {
|
||||
<CardTitle className="text-2xl font-bold">站点公告</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="p-6">
|
||||
{loading ? (
|
||||
<Skeleton className="h-20 w-full" />
|
||||
) : announcements.length > 0 ? (
|
||||
announcements.map((announcement, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="mb-4 last:mb-0 bg-gray-50 p-4 rounded-lg"
|
||||
>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className="bg-teal-100 text-teal-800 mb-2"
|
||||
>
|
||||
{announcement.date}
|
||||
2024-10-03
|
||||
</Badge>
|
||||
<p className="text-gray-700">{announcement.content}</p>
|
||||
<p className="text-gray-700">目前API已由无数据库的屎山代码重构为使用 Mysql 的高性能代码</p>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<p className="text-gray-500 italic">暂无公告</p>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -224,7 +198,7 @@ export default function ApiDocsComponent() {
|
||||
</CardHeader>
|
||||
<CardContent className="p-6">
|
||||
<p className="text-gray-700">
|
||||
此 API 提供随机二次元图片,不定期更新!
|
||||
此 API 提供随机二次元图片,不定期更新!
|
||||
</p>
|
||||
<p className="mt-4 text-gray-600">
|
||||
图片总数:{" "}
|
||||
@ -283,7 +257,7 @@ export default function ApiDocsComponent() {
|
||||
<TableCell>{endpoint.id}</TableCell>
|
||||
<TableCell>{endpoint.device}</TableCell>
|
||||
<TableCell>{endpoint.method}</TableCell>
|
||||
<TableCell>{endpoint.url}</TableCell>
|
||||
<TableCell><a href = {endpoint.url}>{endpoint.url}</a></TableCell>
|
||||
<TableCell>{endpoint.description}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
|
@ -1,12 +1,39 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import crypto from 'crypto';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const generateProjectHash = () => {
|
||||
const hash = crypto.createHash('sha256');
|
||||
const walk = (dir) => {
|
||||
const files = fs.readdirSync(dir);
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(dir, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isDirectory()) {
|
||||
walk(filePath);
|
||||
} else {
|
||||
hash.update(fs.readFileSync(filePath));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
walk(path.join(__dirname, '..'));
|
||||
return hash.digest('hex').substring(0, 7); // 使用前10个字符作为短哈希
|
||||
};
|
||||
|
||||
const generateBuildId = () => {
|
||||
const buildId = Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
|
||||
const projectHash = generateProjectHash();
|
||||
const envFilePath = path.join(__dirname, '..', '.env.local');
|
||||
|
||||
fs.appendFileSync(envFilePath, `\nNEXT_PUBLIC_BUILD_ID=${buildId}`);
|
||||
console.log(`Build ID generated: ${buildId}`);
|
||||
if (fs.existsSync(envFilePath)) {
|
||||
fs.unlinkSync(envFilePath);
|
||||
}
|
||||
|
||||
fs.writeFileSync(envFilePath, `NEXT_PUBLIC_BUILD_ID=${projectHash}`);
|
||||
console.log(`Build ID generated: ${projectHash}`);
|
||||
};
|
||||
|
||||
generateBuildId();
|
Loading…
Reference in New Issue
Block a user