Skip to content

Latest commit

 

History

History
495 lines (369 loc) · 9.17 KB

File metadata and controls

495 lines (369 loc) · 9.17 KB

Pluto 接口文档(中文)

本文档描述 Pluto 项目对外提供的 HTTP API,供 App 接入使用。

基础地址

{BASE_URL}/api

BASE_URL 为部署域名,例如 https://example.com

鉴权

公共接口

无需鉴权。

管理后台接口

需要管理员登录后的 Cookie(photos_admin)。

  • Cookie 名称:photos_admin
  • HTTP-only

通用响应

大多数接口返回 JSON:

  • ok: true | false
  • 失败时包含 errorerr

分页

常用参数:

  • page(默认 1)
  • pageSize(默认 20)

返回字段:

  • total
  • totalPages

公共接口

照片列表

GET /media/list

Query 参数:

  • q: 关键词(文件名/标题/位置)
  • category: 分类 slug 或 id
  • tag: 标签
  • page
  • pageSize
  • sort: date | likes | views(默认 date
  • orientation: landscape | portrait | square

排序规则:

  • date:优先按 datetime_original,为空时回退 created_at

响应示例:

{
  "ok": true,
  "results": [
    {
      "id": "...",
      "url": "...",
      "url_thumb": "...",
      "url_medium": "...",
      "url_large": "...",
      "filename": "...",
      "alt": "...",
      "size": 0,
      "width": 0,
      "height": 0,
      "created_at": "2024-01-01T00:00:00.000Z",
      "camera_make": "...",
      "camera_model": "...",
      "lens_model": "...",
      "aperture": "...",
      "shutter_speed": "...",
      "iso": "...",
      "focal_length": "...",
      "datetime_original": "2024-01-01T00:00:00.000Z",
      "location_name": "...",
      "categories": [{ "id": "...", "name": "...", "slug": "..." }],
      "category_ids": ["..."],
      "tags": ["..."],
      "likes": 0,
      "view_count": 0,
      "liked": false
    }
  ],
  "total": 0,
  "page": 1,
  "pageSize": 20,
  "totalPages": 0
}

照片分类

GET /media/categories

说明:仅返回 show_in_frontend = 1 的分类。

响应:

{
  "ok": true,
  "categories": [
    {
      "id": "...",
      "name": "...",
      "slug": "...",
      "description": "...",
      "media_count": 0
    }
  ]
}

照片详情

GET /media/{id}

说明:获取单张照片的完整信息,仅返回公开的照片(visibility = 'public'NULL)。

响应:

{
  "ok": true,
  "data": {
    "id": "...",
    "url": "...",
    "url_thumb": "...",
    "url_medium": "...",
    "url_large": "...",
    "filename": "...",
    "title": "...",
    "alt": "...",
    "width": 1920,
    "height": 1080,
    "size": 123456,
    "mime_type": "image/jpeg",
    "camera_make": "...",
    "camera_model": "...",
    "lens_model": "...",
    "aperture": "f/2.8",
    "shutter_speed": "1/100",
    "iso": "100",
    "focal_length": "50mm",
    "datetime_original": "...",
    "location_name": "...",
    "categories": [{ "id": "...", "name": "...", "slug": "..." }],
    "tags": ["tag1", "tag2"],
    "likes": 10,
    "view_count": 120,
    "liked": false,
    "created_at": "2026-02-07T12:34:56.789Z"
  }
}

照片浏览量

GET /media/{id}/view POST /media/{id}/view

  • GET:获取当前浏览量。
  • POST:记录一次浏览(会忽略常见爬虫 UA;当配置 KV 时,5 分钟内同 IP 重复浏览会去重)。

响应:

{ "ok": true, "views": 123 }

照片点赞

GET /media/{id}/like POST /media/{id}/like DELETE /media/{id}/like

  • 点赞状态由 HTTP-only Cookie 记录。

响应:

{ "ok": true, "likes": 0, "liked": true }

相册列表

GET /albums

Query 参数:

  • page
  • pageSize
  • q
  • category(分类 slug 或 id)

响应:

{
  "ok": true,
  "albums": [
    {
      "id": "...",
      "title": "...",
      "description": "...",
      "cover_media_id": "...",
      "cover_media": { "id": "...", "url": "...", "url_thumb": "...", "url_medium": "..." },
      "created_at": "...",
      "updated_at": "...",
      "media_count": 0,
      "views": 0,
      "likes": 0,
      "slug": "...",
      "is_protected": false,
      "categories": [{ "id": "...", "name": "...", "slug": "..." }],
      "category_ids": ["..."]
    }
  ],
  "total": 0,
  "totalPages": 0
}

相册分类

GET /albums/categories

说明:仅返回 show_in_frontend = 1 的分类。

响应:

{
  "ok": true,
  "categories": [
    {
      "id": "...",
      "name": "...",
      "slug": "...",
      "description": "...",
      "media_count": 0
    }
  ]
}

相册详情

GET /albums/{idOrSlug}

  • 密码相册需 Authorization: Bearer {token}
  • 未提供或无效会返回 403{ code: "PASSWORD_REQUIRED" }

响应:

{ "ok": true, "data": { ...album } }

相册照片

GET /albums/{idOrSlug}/media

Query 参数:

  • page

  • pageSize

  • 密码相册需 Authorization: Bearer {token}

响应:

{ "ok": true, "media": [ ...media ], "total": 0 }

相册解锁(密码)

POST /albums/{idOrSlug}/unlock

Body:

{ "password": "..." }

响应:

{ "ok": true, "token": "..." }

相册浏览数

GET /albums/{id}/view POST /albums/{id}/view

  • POST 会增加浏览次数(有 IP 限制)。

响应:

{ "views": 0 }

相册点赞

GET /albums/{id}/like POST /albums/{id}/like DELETE /albums/{id}/like

  • 点赞状态由 HTTP-only Cookie 记录。

响应:

{ "ok": true, "likes": 0, "liked": true }

相册评论

GET /albums/{id}/comments

响应:

{ "ok": true, "comments": [ ... ], "isAdmin": false }

POST /albums/{id}/comments

Body:

{
  "author_name": "...",
  "author_email": "...",
  "author_url": "...",
  "content": "...",
  "parent_id": "..."
}

响应:

{ "ok": true, "data": { "id": "...", "status": "pending" } }

评论审核(管理员)

POST /albums/{id}/comments/{commentId}/approve

评论删除(当前无权限校验)

DELETE /albums/{id}/comments/{commentId}

注意:当前删除接口未做鉴权,生产环境建议限制为管理员。

订阅

GET /subscribe

响应:

{ "ok": true, "enabled": true }

POST /subscribe

Body:

{ "email": "user@example.com" }

响应:

{ "ok": true, "token": "..." }

管理后台接口

所有后台接口需要 photos_admin Cookie。

登录与会话

  • POST /admin/login

    • Body: { "username": "...", "password": "..." }
    • 成功会写入 photos_admin Cookie
  • POST /admin/logout

    • 清除 Cookie
  • GET /admin/me

    • 返回 { ok: true, user: "..." }

媒体

  • GET /admin/media/list

    • Query: q, category, tag, page, pageSize, sort
    • sort: date | date_asc | name | likes | views
  • GET /admin/media/{id}

  • PUT /admin/media/{id}

    • Body: { title, alt, category_ids, tags, visibility }
  • DELETE /admin/media/{id}

  • POST /admin/media/upload

    • multipart/form-data
    • 字段: filefiles(支持多文件)、providertitlealtfoldercategory_ids(逗号分隔)、tags(逗号分隔)、visibility

媒体分类

  • GET /admin/media/categories

  • POST /admin/media/categories

    • Body: { name, slug, description, display_order, show_in_frontend }
  • PUT /admin/media/categories/{id}

    • Body: { name, slug, description, display_order, show_in_frontend }
  • DELETE /admin/media/categories/{id}

媒体标签

  • GET /admin/media/tags

设备统计

  • GET /admin/media/devices
    • 返回相机/镜头统计

存储方式

  • GET /admin/providers
    • 返回可用存储与默认值

相册

  • GET /admin/albums

    • Query: page, pageSize, q
  • POST /admin/albums

    • Body: { title, description, cover_media_id, slug, tags, category_ids, password, status }
  • GET /admin/albums/{id}

  • PUT /admin/albums/{id}

    • Body: { title, description, cover_media_id, slug, tags, category_ids, password, status }
  • DELETE /admin/albums/{id}

  • GET /admin/albums/{id}/media

  • POST /admin/albums/{id}/media

    • Body: { media_ids: ["..."] }
  • DELETE /admin/albums/{id}/media

    • Body: { media_ids: ["..."] }
  • POST /admin/albums/{id}/otp

    • 返回 { ok: true, otp: "..." }

相册分类

  • GET /admin/albums/categories

  • POST /admin/albums/categories

    • Body: { name, slug, description, display_order, show_in_frontend }
  • PUT /admin/albums/categories/{id}

    • Body: { name, slug, description, display_order, show_in_frontend }
  • DELETE /admin/albums/categories/{id}

相册评论

  • GET /admin/album-comments

    • Query: page, pageSize, statusall | pending | approved
  • POST /admin/album-comments/{id}/approve

  • DELETE /admin/album-comments/{id}

邮件通知

  • GET /admin/newsletters

    • Query: page, pageSize
  • POST /admin/newsletters

    • 创建: { subject, content, type }
    • 发送: { action: "send", id: "newsletterId" }
    • 发送成功响应:
      • { ok: true, sent, total, failed, failedRecipients? }
    • 发送失败响应:
      • { ok: false, code, error, sent, total, failed, failedRecipients? }
    • 常见发送错误码:
      • NOT_FOUND(newsletter 不存在或已发送)
      • SERVER_ERROR(邮件服务配置或发送异常)

订阅用户

  • GET /admin/subscribers
    • Query: page, pageSize