From f110beb5dc0aa39db2ee9b17767019aa5fae0126 Mon Sep 17 00:00:00 2001 From: lsy Date: Mon, 10 Mar 2025 17:22:18 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=85=A8=E9=83=A8=E6=94=B9=E6=88=90=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=BC=8F=E9=83=A8=E4=BB=B6=202.=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E7=94=A8=E8=84=9A=E6=9C=AC=E5=88=9B=E5=BB=BA=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- create_post.sh | 55 +++++ src/components/GitProjectCollection.tsx | 103 ++++++---- src/components/Layout.astro | 4 +- src/components/MediaGrid.astro | 7 +- src/components/WorldHeatmap.tsx | 17 +- src/consts.ts | 24 +-- src/content.config.ts | 27 --- src/content/{ => web}/MDX使用教程.mdx | 0 src/content/web/echoes博客使用说明.md | 255 ++++++++++++++++++++++++ src/content/博客使用说明.md | 226 --------------------- src/pages/api/articles.ts | 13 -- src/pages/api/douban.ts | 13 +- src/pages/api/git-projects.ts | 156 ++++++++------- src/pages/books.astro | 8 +- src/pages/movies.astro | 8 +- src/pages/other.astro | 10 +- src/pages/projects.astro | 14 +- 17 files changed, 504 insertions(+), 436 deletions(-) create mode 100644 create_post.sh rename src/content/{ => web}/MDX使用教程.mdx (100%) create mode 100644 src/content/web/echoes博客使用说明.md delete mode 100644 src/content/博客使用说明.md diff --git a/create_post.sh b/create_post.sh new file mode 100644 index 0000000..119c6aa --- /dev/null +++ b/create_post.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# 获取脚本所在目录的上级目录(假设脚本在项目根目录) +PROJECT_ROOT="$(cd "$(dirname "$0")" && pwd)" + +# 如果没有提供参数,使用交互式输入 +if [ "$#" -lt 2 ]; then + read -rp "请输入文章标题: " TITLE + read -rp "请输入文章路径 (例如: web/my-post): " PATH_ARG +else + TITLE=$1 + PATH_ARG=$2 +fi + +# 检查输入是否为空 +if [ -z "$TITLE" ] || [ -z "$PATH_ARG" ]; then + echo "错误: 标题和路径不能为空" + echo "使用方法: $0 <标题> <路径>" + echo "示例: $0 \"我的新文章\" \"web/my-post\"" + exit 1 +fi + +# 获取当前时间,格式化为ISO 8601格式 +CURRENT_DATE=$(date +"%Y-%m-%dT%H:%M:%S%:z") + +# 构建完整的文件路径 +CONTENT_DIR="$PROJECT_ROOT/src/content" +FULL_PATH="$CONTENT_DIR/$PATH_ARG" + +# 确保路径存在 +mkdir -p "$FULL_PATH" + +# 构建最终的文件路径 +FILENAME="$FULL_PATH/$(basename "$PATH_ARG").md" +ABSOLUTE_PATH="$(cd "$(dirname "$FILENAME")" 2>/dev/null && pwd)/$(basename "$FILENAME")" + +# 检查文件是否已存在 +if [ -f "$FILENAME" ]; then + echo "错误: 文章已存在: $ABSOLUTE_PATH" + read -rp "按回车键退出..." + exit 1 +fi + +# 创建markdown文件 +cat > "$FILENAME" << EOF +--- +title: "$TITLE" +date: $CURRENT_DATE +tags: [] +--- +hello,world +EOF + +echo "已创建新文章: $ABSOLUTE_PATH" +read -rp "按回车键退出..." \ No newline at end of file diff --git a/src/components/GitProjectCollection.tsx b/src/components/GitProjectCollection.tsx index 59c38f4..b0831ad 100644 --- a/src/components/GitProjectCollection.tsx +++ b/src/components/GitProjectCollection.tsx @@ -1,6 +1,5 @@ import React, { useState, useEffect } from 'react'; import ReactMasonryCss from 'react-masonry-css'; -import { GIT_CONFIG } from '@/consts'; // Git 平台类型枚举 export enum GitPlatform { @@ -9,30 +8,37 @@ export enum GitPlatform { GITEE = 'gitee' } -// 内部使用的平台配置 - 用户不需要修改 -export const GIT_PLATFORM_CONFIG = { - platforms: { - [GitPlatform.GITHUB]: { - ...GIT_CONFIG.github, - apiUrl: 'https://api.github.com' - }, - [GitPlatform.GITEA]: { - ...GIT_CONFIG.gitea - }, - [GitPlatform.GITEE]: { - ...GIT_CONFIG.gitee, - apiUrl: 'https://gitee.com/api/v5' - } - }, - enabledPlatforms: [GitPlatform.GITHUB, GitPlatform.GITEA, GitPlatform.GITEE], - platformNames: { - [GitPlatform.GITHUB]: 'GitHub', - [GitPlatform.GITEA]: 'Gitea', - [GitPlatform.GITEE]: 'Gitee' - } +// Git 配置接口 +export type GitConfig = { + username: string; + token?: string; + perPage?: number; + url?: string; }; +// 平台默认配置 +export const DEFAULT_GIT_CONFIG = { + perPage: 10, + giteaUrl: '' +}; +// 内部使用的平台配置 +export const GIT_PLATFORM_CONFIG = { + platforms: { + [GitPlatform.GITHUB]: { + apiUrl: 'https://api.github.com' + }, + [GitPlatform.GITEA]: {}, + [GitPlatform.GITEE]: { + apiUrl: 'https://gitee.com/api/v5' + } + }, + platformNames: { + [GitPlatform.GITHUB]: 'GitHub', + [GitPlatform.GITEA]: 'Gitea', + [GitPlatform.GITEE]: 'Gitee' + } +}; interface GitProject { name: string; @@ -59,13 +65,15 @@ interface GitProjectCollectionProps { username?: string; organization?: string; title?: string; + config: GitConfig; } const GitProjectCollection: React.FC = ({ platform, username, organization, - title + title, + config }) => { const [projects, setProjects] = useState([]); const [pagination, setPagination] = useState({ current: 1, total: 1, hasNext: false, hasPrev: false }); @@ -73,36 +81,49 @@ const GitProjectCollection: React.FC = ({ const [error, setError] = useState(null); const [isPageChanging, setIsPageChanging] = useState(false); - // 获取默认用户名 - const defaultUsername = GIT_PLATFORM_CONFIG.platforms[platform].username; - // 使用提供的用户名或默认用户名 - const effectiveUsername = username || defaultUsername; + const effectiveUsername = username || config.username; const fetchData = async (page = 1) => { setLoading(true); - const params = new URLSearchParams(); - params.append('platform', platform); - params.append('page', page.toString()); - if (effectiveUsername) { - params.append('username', effectiveUsername); + if (!platform || !Object.values(GitPlatform).includes(platform)) { + setError('无效的平台参数'); + setLoading(false); + return; } - if (organization) { - params.append('organization', organization); - } - - const url = `/api/git-projects?${params.toString()}`; - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error(`获取数据失败: ${response.status} ${response.statusText}`); + const baseUrl = new URL('/api/git-projects', window.location.origin); + + baseUrl.searchParams.append('platform', platform); + baseUrl.searchParams.append('page', page.toString()); + baseUrl.searchParams.append('config', JSON.stringify(config)); + + if (effectiveUsername) { + baseUrl.searchParams.append('username', effectiveUsername); } + + if (organization) { + baseUrl.searchParams.append('organization', organization); + } + + const response = await fetch(baseUrl.toString(), { + method: 'GET', + headers: { + 'Accept': 'application/json' + } + }); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(`请求失败: ${response.status} ${response.statusText}\n${JSON.stringify(errorData, null, 2)}`); + } + const data = await response.json(); setProjects(data.projects); setPagination(data.pagination); } catch (err) { + console.error('请求错误:', err); setError(err instanceof Error ? err.message : '未知错误'); } finally { setLoading(false); diff --git a/src/components/Layout.astro b/src/components/Layout.astro index f9d5f28..910e5af 100644 --- a/src/components/Layout.astro +++ b/src/components/Layout.astro @@ -2,7 +2,7 @@ import "@/styles/global.css"; import Header from "@/components/header.astro"; import Footer from "@/components/Footer.astro"; -import { ICP, PSB_ICP, PSB_ICP_URL, SITE_NAME } from "@/consts"; +import { ICP, PSB_ICP, PSB_ICP_URL, SITE_NAME, SITE_DESCRIPTION } from "@/consts"; // 定义Props接口 interface Props { @@ -18,7 +18,7 @@ interface Props { const canonicalURL = new URL(Astro.url.pathname, Astro.site); // 从props中获取页面特定信息 -const { title = SITE_NAME, description, date, author, tags, image } = Astro.props; +const { title = SITE_NAME, description = SITE_DESCRIPTION, date, author, tags, image } = Astro.props; --- diff --git a/src/components/MediaGrid.astro b/src/components/MediaGrid.astro index 55a58b2..52372dc 100644 --- a/src/components/MediaGrid.astro +++ b/src/components/MediaGrid.astro @@ -2,9 +2,10 @@ interface Props { type: 'movie' | 'book'; title: string; + doubanId: string; } -const { type, title } = Astro.props; +const { type, title, doubanId } = Astro.props; ---
@@ -24,7 +25,7 @@ const { type, title } = Astro.props;
-