6.6 KiB
6.6 KiB
🐉 Loongyan
一个轻量级、自托管的全栈相册管理系统。无需数据库,直接以文件系统存储,支持图片和视频,提供动态缩略图生成和现代化的 Web 界面。
✨ 功能特性
- 📁 零配置相册管理 - 直接扫描
data/文件夹,子目录自动识别为相册 - 🖼️ 多格式支持 - 支持 JPEG、PNG、GIF、BMP、WebP 及 MP4、MOV 等视频格式
- ⚡ 动态缩略图 - 基于 libvips 实时生成,支持自定义尺寸参数
- 🌊 流式传输 - 大文件流式输出,节省内存,防止泄漏
- 🎨 现代化界面 - SvelteKit 5 驱动,响应式设计,流畅体验
- 🔧 高性能解析 - 自定义二进制解析器读取图片尺寸,无需 ImageMagick
- 🐳 Docker 支持 - 多阶段构建,一键部署
- 🌍 国际化 - 支持中英文切换(Paraglide JS)
- 🔐 用户认证 - 集成 Better Auth 认证系统
🏗️ 项目结构
loongyan/
├── bin/ # Dart 后端服务器
│ ├── server.dart # 服务入口
│ ├── router.dart # API 路由定义
│ ├── middleware/ # 中间件(异常处理等)
│ ├── domain/ # 领域层
│ │ ├── entities/ # 实体(Album, Photo)
│ │ └── repositories/ # 数据仓库
│ └── util/ # 工具类(Vips 图片处理)
├── web/ # SvelteKit 前端
│ ├── src/
│ │ ├── lib/
│ │ │ ├── components/ # UI 组件
│ │ │ └── server/ # 服务端逻辑
│ │ └── routes/ # 页面路由
│ └── package.json
├── data/ # 数据目录(相册文件夹)
├── cache/ # 缩略图缓存
├── Dockerfile # 容器化配置
└── pubspec.yaml # Dart 依赖
🚀 快速开始
环境要求
- 后端: Dart SDK ^3.10.7, libvips
- 前端: Node.js 18+, pnpm/npm
1. 克隆项目
git clone <repository-url>
cd loongyan
2. 准备数据目录
mkdir -p data/我的相册
cp /path/to/your/photos/* data/我的相册/
3. 运行后端
# 安装依赖
dart pub get
# 开发运行(端口 8080)
dart run bin/server.dart
# 输出: Server listening on port 8080
4. 运行前端
cd web
pnpm install
pnpm dev
# 访问 http://localhost:5173
🐳 Docker 部署
构建镜像
docker build . -t loongyan
运行容器
docker run -d \
--name loongyan \
-p 8080:8080 \
-v $(pwd)/data:/app/data \
-v $(pwd)/cache:/app/cache \
loongyan
Docker Compose(推荐)
version: '3.8'
services:
loongyan:
build: .
ports:
- "8080:8080"
volumes:
- ./data:/app/data
- ./cache:/app/cache
environment:
- PORT=8080
restart: unless-stopped
docker-compose up -d
📡 API 文档
基础信息
- 基础 URL:
http://localhost:8080/api/v1 - 响应格式: JSON
端点列表
| 方法 | 端点 | 描述 | 参数 |
|---|---|---|---|
| GET | / |
测试接口 | - |
| GET | /album |
获取所有相册 | - |
| GET | /album/<id> |
获取相册详情 | id: 相册ID |
| GET | /album/<id>/photo |
获取相册内照片 | id: 相册ID |
| GET | /photo/<id> |
获取照片元数据 | id: 照片ID |
| GET | /photo/<id>/file |
获取原图文件 | id: 照片ID |
| GET | /photo/<id>/preview |
获取缩略图 | id: 照片ID, w: 宽度, h: 高度 |
| GET | /echo/<message> |
回声测试 | message: 任意消息 |
示例请求
# 获取相册列表
curl http://localhost:8080/api/v1/album
# 获取相册内照片
curl http://localhost:8080/api/v1/album/123456/photo
# 获取缩略图(宽度 300px)
curl http://localhost:8080/api/v1/photo/789012/preview?w=300
响应示例
相册列表 (GET /album)
[
{
"id": 123456789,
"name": "我的相册",
"createdAt": "2024-01-15T08:30:00.000",
"updatedAt": "2024-01-15T08:30:00.000"
}
]
照片详情 (GET /photo/<id>)
{
"id": 987654321,
"albumId": 123456789,
"filePath": "data/我的相册/IMG_001.jpg",
"fileName": "IMG_001.jpg",
"fileSize": 2048576,
"mimeType": "image/jpeg",
"width": 1920,
"height": 1080,
"createdAt": "2024-01-15T08:30:00.000"
}
🛠️ 开发指南
后端开发
# 运行测试
dart test
# 代码检查
dart analyze
# 格式化代码
dart format .
# AOT 编译(生产)
dart compile exe bin/server.dart -o bin/server
前端开发
cd web
# 安装依赖
pnpm install
# 开发服务器
pnpm dev
# 构建生产版本
pnpm build
# 预览生产构建
pnpm preview
# 运行测试
pnpm test
# 代码检查
pnpm lint
# 格式化
pnpm format
# 类型检查
pnpm check
生成认证 Schema
cd web
pnpm auth:schema
⚙️ 配置说明
后端环境变量
| 变量名 | 默认值 | 说明 |
|---|---|---|
PORT |
8080 |
服务器监听端口 |
前端环境变量
前端使用 .env 文件配置,参考 .env.example:
# web/.env
PUBLIC_API_URL=http://localhost:8080/api/v1
📦 技术栈
后端
- Dart - 编程语言
- Shelf - Web 框架
- shelf_router - 路由库
- libvips - 高性能图片处理
前端
- Svelte 5 - 前端框架
- SvelteKit - 全栈框架
- Vite - 构建工具
- Better Auth - 认证库
- Paraglide JS - 国际化
- Drizzle ORM - 数据库 ORM
🤝 贡献指南
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/amazing-feature) - 提交更改 (
git commit -m 'Add amazing feature') - 推送到分支 (
git push origin feature/amazing-feature) - 创建 Pull Request
🙏 致谢
Made with ❤️ by Loongyan Team