feat: scaffold seafile resource sync

This commit is contained in:
SepComet
2026-05-05 10:30:47 +08:00
parent fdeb25805c
commit 8265a10cff
10 changed files with 506 additions and 97 deletions
+21 -1
View File
@@ -1,5 +1,6 @@
---
import { site } from '../config';
import type { ProjectDownload } from '../data/loaders';
interface Props {
name: string;
@@ -11,6 +12,7 @@ interface Props {
featured?: boolean;
demoVideo?: string;
downloadLink?: string;
downloads?: ProjectDownload[];
}
const {
@@ -23,10 +25,12 @@ const {
featured = false,
demoVideo = '',
downloadLink = '',
downloads = [],
} = Astro.props;
const fallbackRepoUrl = repo ? `${site.gitea.url}/${repo}` : '';
const resolvedRepoUrl = repoUrl || fallbackRepoUrl;
const visibleDownloads = downloads.filter((item) => item.name || item.url);
---
<article class="card">
@@ -57,10 +61,26 @@ const resolvedRepoUrl = repoUrl || fallbackRepoUrl;
Demo
</a>
) : null}
{downloadLink ? (
{downloadLink && visibleDownloads.length === 0 ? (
<a class="section-link" href={downloadLink} target="_blank" rel="noreferrer">
下载
</a>
) : null}
</div>
{
visibleDownloads.length > 0 ? (
<div class="project-links" style="margin-top: 0.75rem; flex-wrap: wrap; gap: 0.6rem 0.8rem;">
{visibleDownloads.map((item) =>
item.url ? (
<a class="section-link" href={item.url} target="_blank" rel="noreferrer">
{item.name}
</a>
) : (
<span class="tag">{item.name}</span>
),
)}
</div>
) : null
}
</article>
+28
View File
@@ -0,0 +1,28 @@
{
"projects": [
{
"project_repo": "basil/personal-homepage",
"downloads": [
{
"name": "Windows 构建包",
"description": "项目打包文件(可选)",
"url": "http://106.12.111.150:8000/f/5eb1877a7212488ca0aa/?dl=1",
"repo_id": "",
"path": "",
"type": "build",
"platform": "windows"
}
]
}
],
"shares": [
{
"name": "简历 PDF",
"description": "独立公开资源示例,可不绑定项目。",
"url": "",
"repo_id": "",
"path": "",
"type": "document"
}
]
}
+19 -3
View File
@@ -2,6 +2,17 @@ import { readFile } from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
export type ProjectDownload = {
name: string;
description?: string;
url?: string;
type?: 'build' | 'demo' | 'document' | 'asset';
platform?: string;
size?: number;
updated_at?: string;
source?: 'seed' | 'seafile';
};
type ProjectSeed = {
name: string;
description: string;
@@ -9,6 +20,7 @@ type ProjectSeed = {
cover_image: string;
demo_video?: string;
download_link?: string;
downloads?: ProjectDownload[];
tags: string[];
featured: boolean;
};
@@ -21,12 +33,16 @@ export type ProjectData = ProjectSeed & {
type ShareSeed = {
name: string;
description: string;
url: string;
time: string;
description?: string;
url?: string;
time?: string;
};
export type ShareData = ShareSeed & {
type?: 'build' | 'demo' | 'document' | 'asset';
project?: string;
project_repo?: string;
platform?: string;
size?: number;
source?: 'seed' | 'seafile';
updated_at?: string;
+1
View File
@@ -114,6 +114,7 @@ const activeRepo = activity.recent[0]?.repo ?? featuredProjects[0]?.gitea_repo ?
featured={project.featured}
demoVideo={project.demo_video}
downloadLink={project.download_link}
downloads={project.downloads}
/>
))
}
+1
View File
@@ -33,6 +33,7 @@ const projects = await loadProjects();
featured={project.featured}
demoVideo={project.demo_video}
downloadLink={project.download_link}
downloads={project.downloads}
/>
))
}
+12 -3
View File
@@ -23,12 +23,21 @@ const shares = await loadShares();
{shares.map((share) => (
<article class="card">
<p class="log-meta">
<span class="mono">{share.time}</span>
<span class="mono">{share.updated_at || share.time || '未标注时间'}</span>
{share.project ? <span class="tag">{share.project}</span> : null}
{share.type ? <span class="tag tag--tech">{share.type}</span> : null}
</p>
<h2 class="project-title">{share.name}</h2>
<p>{share.description}</p>
{share.description ? <p>{share.description}</p> : null}
{share.project_repo ? <p class="activity-copy mono">{share.project_repo}</p> : null}
<div class="project-links" style="margin-top: 1rem;">
<a class="section-link" href={share.url}>打开链接</a>
{share.url ? (
<a class="section-link" href={share.url} target="_blank" rel="noreferrer">
打开链接
</a>
) : (
<span class="tag">链接待补充</span>
)}
</div>
</article>
))}