{"openapi":"3.0.3","info":{"title":"OSS API","description":"对象存储与 CDN 管理 API。支持 Cookie Session（浏览器）与 API Key（Header + 签名）两种认证。","version":"1.0.0"},"servers":[{"url":"https://oss.lonae.com"}],"security":[{"cookieSession":[]},{"apiKey":[]}],"tags":[{"name":"文件","description":"文件上传、下载、元数据、删除、ACL、复制、分片上传"},{"name":"文件夹","description":"列表、创建、元数据、删除、ACL"},{"name":"分享与短链","description":"分享链接、短链、预签名下载"},{"name":"账户","description":"用量与配额"}],"paths":{"/api/files/upload":{"post":{"tags":["文件"],"summary":"单文件上传","description":"multipart/form-data 上传单个文件，可选 folderId 指定目标文件夹。大文件建议使用分片上传（init → part × N → complete）。","security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"文件内容"},"folderId":{"type":"string","format":"uuid","nullable":true,"description":"目标文件夹 ID，不传则为根目录"}}}}}},"responses":{"200":{"description":"上传成功","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"}}}}}},"400":{"description":"缺少文件或 folderId 无效"},"401":{"description":"未登录或 API Key 无效"},"500":{"description":"写入存储失败"}}}},"/api/files/multipart/init":{"post":{"tags":["文件"],"summary":"分片上传初始化","description":"创建分片上传任务，返回 uploadId。请求体：{ key, name, mimeType, folderId? }。","security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"mimeType":{"type":"string"},"folderId":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"返回 uploadId"},"401":{"description":"未认证"}}}},"/api/files/multipart/part":{"put":{"tags":["文件"],"summary":"上传分片","description":"上传单个分片。Query: uploadId, partNumber。Body: 二进制。","security":[{"cookieSession":[]},{"apiKey":[]}],"parameters":[{"name":"uploadId","in":"query","required":true,"schema":{"type":"string"}},{"name":"partNumber","in":"query","required":true,"schema":{"type":"integer"}}],"requestBody":{"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"返回 etag"},"401":{"description":"未认证"}}}},"/api/files/multipart/complete":{"post":{"tags":["文件"],"summary":"完成分片上传","description":"合并所有分片并写入文件元数据。请求体：{ uploadId, parts: [{ partNumber, etag }] }。","security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"uploadId":{"type":"string"},"parts":{"type":"array","items":{"type":"object","properties":{"partNumber":{"type":"integer"},"etag":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"返回文件 id"},"401":{"description":"未认证"}}}},"/api/files/{id}":{"get":{"tags":["文件"],"summary":"获取文件元数据","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"文件元数据"},"401":{"description":"未认证"},"404":{"description":"文件不存在"}}},"head":{"tags":["文件"],"summary":"HEAD 文件（仅返回头信息）","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"头信息"},"404":{"description":"文件不存在"}}},"patch":{"tags":["文件"],"summary":"更新文件（移动目录或 ACL）","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"targetFolderId":{"type":"string","nullable":true},"acl":{"type":"string","enum":["private","public-read","public-read-write"]}}}}}},"responses":{"200":{"description":"ok"},"400":{"description":"参数错误"},"401":{"description":"未认证"}}},"delete":{"tags":["文件"],"summary":"删除文件（软删除进回收站）","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"ok"},"400":{"description":"失败"},"401":{"description":"未认证"}}}},"/api/files/batch-delete":{"post":{"tags":["文件"],"summary":"批量删除文件","security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["ids"],"properties":{"ids":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"results"},"400":{"description":"ids 无效"},"401":{"description":"未认证"}}}},"/api/files/{id}/copy":{"post":{"tags":["文件"],"summary":"复制文件到目标文件夹","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"targetFolderId":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"返回新文件 id"},"400":{"description":"失败"},"401":{"description":"未认证"}}}},"/api/files/{id}/download":{"get":{"tags":["文件"],"summary":"下载文件","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"文件流","headers":{"Content-Type":{},"Content-Disposition":{}}},"401":{"description":"未认证"},"404":{"description":"文件不存在或已删除"},"500":{"description":"读取失败"}}}},"/api/files/{id}/preview":{"get":{"tags":["文件"],"summary":"预览文件","description":"返回文件流，用于内嵌预览（如图片）。","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"文件流"},"401":{"description":"未认证"},"404":{"description":"文件不存在"}}}},"/api/files/{id}/presigned-url":{"post":{"tags":["文件"],"summary":"生成预签名下载链接","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"expiresIn":{"type":"integer","description":"秒，默认 3600"}}}}}},"responses":{"200":{"description":"{ url, expiresIn }"},"401":{"description":"未认证"},"404":{"description":"文件不存在"}}}},"/api/files/{id}/share":{"post":{"tags":["分享与短链"],"summary":"创建分享链接","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"expiresInDays":{"type":"integer"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"{ token, url, expiresAt }"},"401":{"description":"未认证"},"404":{"description":"文件不存在"}}}},"/api/files/{id}/short-link":{"post":{"tags":["分享与短链"],"summary":"创建短链","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"expiresInSeconds":{"type":"integer"}}}}}},"responses":{"200":{"description":"{ code, url }"},"401":{"description":"未认证"},"404":{"description":"文件不存在"}}}},"/api/folders":{"get":{"tags":["文件夹"],"summary":"列出目录直接子项","description":"query: parentId（不传或空为根目录）、page、pageSize、type、keyword 等。","security":[{"cookieSession":[]},{"apiKey":[]}],"parameters":[{"name":"parentId","in":"query","schema":{"type":"string","nullable":true}},{"name":"page","in":"query","schema":{"type":"integer"}},{"name":"pageSize","in":"query","schema":{"type":"integer"}},{"name":"type","in":"query","schema":{"type":"string","enum":["all","file","folder"]}}],"responses":{"200":{"description":"{ folders, files, total }"},"401":{"description":"未认证"}}},"post":{"tags":["文件夹"],"summary":"创建文件夹","security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"parentId":{"type":"string","nullable":true},"name":{"type":"string"}}}}}},"responses":{"200":{"description":"{ id }"},"400":{"description":"name 无效"},"401":{"description":"未认证"}}}},"/api/folders/{id}":{"get":{"tags":["文件夹"],"summary":"获取文件夹元数据","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"文件夹元数据"},"401":{"description":"未认证"},"404":{"description":"不存在"}}},"patch":{"tags":["文件夹"],"summary":"更新文件夹（ACL）","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"acl":{"type":"string","enum":["private","public-read","public-read-write"]}}}}}},"responses":{"200":{"description":"ok"},"401":{"description":"未认证"}}},"delete":{"tags":["文件夹"],"summary":"删除文件夹（递归）","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"ok"},"400":{"description":"失败"},"401":{"description":"未认证"}}}},"/api/files/multipart/abort":{"delete":{"tags":["文件"],"summary":"中止分片上传","security":[{"cookieSession":[]},{"apiKey":[]}],"parameters":[{"name":"uploadId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"ok"},"401":{"description":"未认证"},"404":{"description":"上传不存在"}}}},"/api/signed":{"get":{"tags":["分享与短链"],"summary":"预签名链接下载","description":"Query: t=token，无需登录。","security":[],"parameters":[{"name":"t","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"文件流"},"403":{"description":"链接无效或已过期"},"404":{"description":"文件不存在"}}}},"/api/quota":{"get":{"tags":["账户"],"summary":"存储用量与配额","security":[{"cookieSession":[]},{"apiKey":[]}],"responses":{"200":{"description":"{ usedBytes, quotaBytes }"},"401":{"description":"未认证"}}}},"/api/usage":{"get":{"tags":["账户"],"summary":"流量与请求统计","security":[{"cookieSession":[]},{"apiKey":[]}],"parameters":[{"name":"days","in":"query","schema":{"type":"integer","description":"默认 30"}}],"responses":{"200":{"description":"{ rows, total }"},"401":{"description":"未认证"}}}},"/api/s/{token}/download":{"get":{"tags":["分享与短链"],"summary":"通过分享 token 下载","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"security":[],"responses":{"200":{"description":"文件流或需输入密码"},"404":{"description":"分享不存在或已过期"}}}},"/f/{id}":{"get":{"tags":["分享与短链"],"summary":"静态资源（按文件 ID）","description":"通过文件 ID 访问静态资源。路径可为 /f/{id} 或 /f/{id}.后缀（如 .jpg），带后缀时查库会忽略后缀仅用 id。公开读文件可直接访问；私有文件需带 query 参数 expires 与 signature。支持图片变换：w、h、q、format（webp/avif）。","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"文件 ID"}},{"name":"expires","in":"query","schema":{"type":"integer","description":"签名过期时间戳（秒），私有文件必传"}},{"name":"signature","in":"query","schema":{"type":"string","description":"HMAC-SHA256 签名，私有文件必传"}}],"security":[],"responses":{"200":{"description":"文件流"},"304":{"description":"未修改（ETag 命中）"},"403":{"description":"私有且未带有效签名或已过期"},"404":{"description":"文件不存在或已删除"}}}},"/go/{code}":{"get":{"tags":["分享与短链"],"summary":"短链跳转","description":"根据短链码重定向到 /f/{文件id}（公开）或带签名的 /f/{id}?expires=&signature=。","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"security":[],"responses":{"302":{"description":"重定向到 /f/{id}"},"404":{"description":"短链不存在或已过期"}}}}},"components":{"securitySchemes":{"cookieSession":{"type":"apiKey","in":"cookie","name":"next-auth.session-token","description":"浏览器登录后 Cookie 中携带的 Session Token。"},"apiKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API Key 认证：Header 中传 X-API-Key（AccessKey:Signature）。Signature 算法：HMAC-SHA256(SecretKey, CanonicalRequest)，CanonicalRequest = Method + \"\\n\" + Path + \"\\n\" + QueryString + \"\\n\" + HashedBody。HashedBody = Hex(SHA256(body))，无 body 时为空字符串。"}}}}