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;
-