CI 测试 / go vet + go test (push) Failing after 5s
- 对象存储直链:S3 引擎 302 到限时预签名 URL(有效期钳位分享剩余时效),失败自动回落代理 - 过期回收:janitor 定时扫描 + 取件惰性回收 + 管理端手动触发(POST /admin/recycle/run), retention_days 最长存储时长;删除走引用计数(去重对象安全) - SHA512 内容去重:三条上传链路落库后计算哈希,命中即复用旧对象并删除本次副本 - 下载防盗链:Referer 白名单(同源/空 Referer/通配域名放行),挂 /share/download - 取件页图片/音频内联预览(下载地址直连,加载失败回退下载按钮) - 文件夹上传:拖拽目录明确提示"建议压缩后上传"(webkitGetAsEntry 探测) - 管理端设置卡「回收与下载安全」8 个新配置键(KVSchema + configKeys + UI + i18n) - 前端产物重建并同步 server/web/dist 与 web-embed - 文档:10-config 配置表、03-file-share 直链/防盗链/文件夹章节、07-admin 回收端点、openapi
452 lines
18 KiB
Markdown
452 lines
18 KiB
Markdown
# 管理后台 API
|
||
|
||
管理端接口:除 `POST /admin/login` 与初始化向导 `/setup` 外,一律要求
|
||
`Authorization: Bearer <token>`(见《认证与限流》),无效令牌 401。
|
||
|
||
## 初始化向导:GET /setup
|
||
|
||
未初始化时返回 HTML 配置页(站点名称、管理员密码、上传/限流/保存策略);
|
||
已初始化时 `303` 重定向到 `/`。
|
||
|
||
```bash
|
||
curl -i http://localhost:8466/setup
|
||
```
|
||
|
||
## 初始化提交:POST /setup
|
||
|
||
表单(浏览器向导)或 JSON 均可;成功后写入库配置 KV 并生成密码哈希与 `jwt_secret`。
|
||
表单提交返回成功 HTML 页;JSON 提交返回 JSON。
|
||
|
||
**主要字段**:
|
||
|
||
| 字段 | 必需 | 默认 | 说明 |
|
||
|---|---|---|---|
|
||
| `admin_password` | ✅ | - | 管理员密码(≥8 位) |
|
||
| `confirm_password` | ✅ | - | 确认密码(须一致) |
|
||
| `site_name` | ❌ | 文件快传 | 站点名称 |
|
||
| `upload_size_value` / `upload_size_unit` | ❌ | 10 / MB | 单文件大小限制(单位 KB/MB/GB) |
|
||
| `save_time_value` / `save_time_unit` | ❌ | 0 / day | 最长保存秒数(0=不限) |
|
||
| `expireStyle` | ❌ | day,hour,minute,forever,count | 过期方式(可多值/逗号分隔) |
|
||
| `code_generate_type` | ❌ | secret | 取件码类型 `number`/`secret` |
|
||
| `errorCount` / `errorMinute` | ❌ | 10 / 1 | 取件错误限流 |
|
||
| `loginCount` / `loginMinute` | ❌ | 5 / 15 | 登录失败限流 |
|
||
| `uploadCount` / `uploadMinute` | ❌ | 10 / 1 | 上传限流 |
|
||
| `allowed_file_types` | ❌ | `*` | 逗号分隔白名单 |
|
||
| `openUpload` / `enableChunk` | ❌ | 1 / 0 | 游客上传 / 分片开关(`1`/`true`/`on`/`yes`) |
|
||
|
||
```bash
|
||
curl -s -X POST http://localhost:8466/setup \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"admin_password":"admin12345","confirm_password":"admin12345","site_name":"我的文件柜","upload_size_value":10,"upload_size_unit":"MB"}'
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "ok": true, "admin": "/#/admin" } }
|
||
```
|
||
|
||
**错误响应**(400,HTML 表单时内嵌错误提示):
|
||
|
||
```json
|
||
{ "code": 400, "msg": "管理员密码至少 8 位" }
|
||
```
|
||
|
||
## 登录:POST /admin/login
|
||
|
||
```bash
|
||
curl -s -X POST http://localhost:8466/admin/login \
|
||
-H 'Content-Type: application/json' \
|
||
-d '{"password":"admin12345"}'
|
||
```
|
||
|
||
**成功响应**(200):
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"id": "admin", "username": "admin",
|
||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||
"token_type": "Bearer",
|
||
"expires_at": 1750000000,
|
||
"expires_in": 604800
|
||
}
|
||
}
|
||
```
|
||
|
||
**错误响应**:
|
||
|
||
```json
|
||
{ "code": 401, "msg": "密码错误" }
|
||
```
|
||
|
||
```json
|
||
{ "code": 423, "msg": "请求次数过多,请稍后再试" }
|
||
```
|
||
|
||
## 校验会话:GET /admin/verify
|
||
|
||
```bash
|
||
curl -s http://localhost:8466/admin/verify -H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "id": "admin", "username": "admin", "token": "eyJ…", "token_type": "Bearer", "expires_at": 1750000000 } }
|
||
```
|
||
|
||
## 登出:POST /admin/logout
|
||
|
||
无状态 JWT,服务端仅返回确认(客户端应丢弃令牌):
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "ok": true } }
|
||
```
|
||
|
||
## 仪表盘:GET /admin/dashboard
|
||
|
||
```bash
|
||
curl -s http://localhost:8466/admin/dashboard -H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"totalFiles": 42,
|
||
"storageUsed": "123456789",
|
||
"sysUptime": 1750000000000,
|
||
"yesterdayCount": 5, "yesterdaySize": "1048576",
|
||
"todayCount": 12, "todaySize": "5242880",
|
||
"activeCount": 40, "expiredCount": 2,
|
||
"textCount": 10, "fileCount": 32, "chunkedCount": 3,
|
||
"usedCount": 156,
|
||
"storageBackend": "local",
|
||
"uploadSizeLimit": 10485760,
|
||
"openUpload": 1, "enableChunk": 1,
|
||
"maxSaveSeconds": 0,
|
||
"topSuffixes": [ { "suffix": ".pdf", "count": 12 }, { "suffix": "Text", "count": 10 } ],
|
||
"recentFiles": [ { "id": 42, "code": "K3P9W", "name": "report.pdf", "size": 1048576, "created_at": "2025-06-01T12:00:00+08:00", "expired_at": "2025-06-08T12:00:00+08:00", "is_expired": false, "expired_count": -1, "used_count": 3, "is_text": false, "is_chunked": false, "is_permanent": false, "has_download_limit": false, "remaining_downloads": null, "file_hash": null, "prefix": "report", "suffix": ".pdf", "text": false, "createdAt": "2025-06-01T12:00:00+08:00", "expiredAt": "2025-06-08T12:00:00+08:00", "isExpired": false, "expiredCount": -1, "usedCount": 3, "isText": false, "isChunked": false, "isPermanent": false, "hasDownloadLimit": false, "remainingDownloads": null, "fileHash": null } ],
|
||
"recentActivities": []
|
||
}
|
||
}
|
||
```
|
||
|
||
> `storageUsed`/`todaySize`/`yesterdaySize` 为字符串字节数;`sysUptime` 为服务启动时刻的 Unix 毫秒。
|
||
|
||
## 文件列表:GET /admin/file/list
|
||
|
||
**参数**:
|
||
|
||
| 参数 | 默认 | 说明 |
|
||
|---|---|---|
|
||
| `page` / `size` | 1 / 10 | 分页(size 1~100) |
|
||
| `keyword` | - | 模糊匹配取件码/文件名/哈希/文本内容 |
|
||
| `status` | - | `active` / `expired` |
|
||
| `type` | - | `text` / `file` / `chunked` |
|
||
| `sortBy` | `created_at` | `created_at`/`expired_at`/`name`/`size`/`used_count`/`code` |
|
||
| `sortOrder` | `desc` | `asc` / `desc` |
|
||
|
||
```bash
|
||
curl -s "http://localhost:8466/admin/file/list?page=1&size=10&status=active&sortBy=size&sortOrder=desc" \
|
||
-H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"page": 1, "size": 10, "total": 40,
|
||
"summary": { "totalFiles": 42, "activeCount": 40, "expiredCount": 2, "textCount": 10, "fileCount": 32, "chunkedCount": 3, "storageUsed": 123456789, "usedCount": 156 },
|
||
"data": [
|
||
{ "id": 42, "code": "K3P9W", "name": "report.pdf", "prefix": "report", "suffix": ".pdf", "size": 1048576, "is_text": false, "is_chunked": false, "is_expired": false, "expired_at": "2025-06-08T12:00:00+08:00", "expired_count": -1, "used_count": 3, "created_at": "2025-06-01T12:00:00+08:00", "has_download_limit": false, "is_permanent": false, "remaining_downloads": null, "file_hash": null, "text": false, "isText": false, "isChunked": false, "isExpired": false, "expiredAt": "2025-06-08T12:00:00+08:00", "expiredCount": -1, "usedCount": 3, "createdAt": "2025-06-01T12:00:00+08:00", "hasDownloadLimit": false, "isPermanent": false, "remainingDownloads": null, "fileHash": null }
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
## 文件详情:GET /admin/file/detail
|
||
|
||
`GET ?id=42` 或 `POST {"id":42}`。返回列表条目字段;文本分享额外含 `content`(全文)。
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "id": 42, "code": "K3P9W", "name": "report.pdf", "size": 1048576, "is_text": false, "expired_at": "2025-06-08T12:00:00+08:00", "expired_count": -1, "used_count": 3, "created_at": "2025-06-01T12:00:00+08:00", "file_hash": null } }
|
||
```
|
||
|
||
```json
|
||
{ "code": 404, "msg": "文件不存在" }
|
||
```
|
||
|
||
## 更新文件:PATCH /admin/file/update
|
||
|
||
更新取件码/文件名(前后缀)/过期策略。**PATCH 为主名,POST 为兼容别名**。
|
||
|
||
**请求体**:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `id` | int | 必需 |
|
||
| `code` | string | 新取件码(冲突 400「code已存在」) |
|
||
| `prefix` / `suffix` | string | 文件名前后缀 |
|
||
| `expired_at` | string | 过期时间(ISO 8601,如 `2025-07-01T00:00:00+08:00`) |
|
||
| `expired_count` | int | 取件次数上限(`-1` 按时间/永久) |
|
||
|
||
```bash
|
||
curl -s -X PATCH http://localhost:8466/admin/file/update \
|
||
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
||
-d '{"id":42,"expired_at":"2025-07-01T00:00:00+08:00","expired_count":10}'
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": "更新成功" }
|
||
```
|
||
|
||
```json
|
||
{ "code": 400, "msg": "code已存在" }
|
||
```
|
||
|
||
## 删除文件:DELETE /admin/file/delete
|
||
|
||
删除分享记录并连带删除存储文件(文本分享无存储文件)。`DELETE` 或 `POST`,请求体 `{"id":42}`。
|
||
|
||
```bash
|
||
curl -s -X DELETE http://localhost:8466/admin/file/delete \
|
||
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -d '{"id":42}'
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": null }
|
||
```
|
||
|
||
```json
|
||
{ "code": 400, "msg": "请选择要删除的文件" }
|
||
```
|
||
|
||
## 批量删除:POST /admin/file/batch-delete
|
||
|
||
`POST` 或 `DELETE`,请求体 `{"ids":[41,42,43]}`。返回逐条统计:
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"requestedCount": 3, "deletedCount": 2, "missingCount": 1, "failedCount": 0,
|
||
"deleted": [41, 42], "missing": [43], "failed": [],
|
||
"requested_count": 3, "deleted_count": 2, "missing_count": 1, "failed_count": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
## 批量更新:PATCH /admin/file/batch-update
|
||
|
||
`PATCH` 或 `POST`。请求体:`ids[]` 必需;`expired_at`(ISO 8601)/`expired_count` 二选一;
|
||
`clearExpiredAt: true`(或 `clear_expired_at`)= 清空过期时间并置 `expired_count=-1`(永久)。
|
||
|
||
```bash
|
||
curl -s -X PATCH http://localhost:8466/admin/file/batch-update \
|
||
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
||
-d '{"ids":[41,42],"clearExpiredAt":true}'
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": { "requestedCount": 2, "updatedCount": 2, "missingCount": 0, "failedCount": 0, "updated": 2, "missing": [], "failed": [], "requested_count": 2, "updated_count": 2, "missing_count": 0, "failed_count": 0 }
|
||
}
|
||
```
|
||
|
||
## 过期策略动作:PATCH /admin/file/policy-action
|
||
|
||
对单个文件执行快捷策略。`PATCH` 或 `POST`。批量版为 `/admin/file/batch-policy-action`(`{"ids":[…]}`),响应结构同批量更新。
|
||
|
||
**请求体**:
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| `id` | 文件 ID |
|
||
| `action` | `extend_24h` / `extend_7d` / `make_permanent` / `reset_download_limit` |
|
||
| `downloadLimit` | 仅 `reset_download_limit` 用:新取件次数(默认 5,须 >0) |
|
||
|
||
```bash
|
||
curl -s -X PATCH http://localhost:8466/admin/file/policy-action \
|
||
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
||
-d '{"id":42,"action":"reset_download_limit","downloadLimit":3}'
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "id": 42, "action": "reset_download_limit" } }
|
||
```
|
||
|
||
```json
|
||
{ "code": 400, "msg": "不支持的策略动作" }
|
||
```
|
||
|
||
> `extend_24h`/`extend_7d` 在当前过期时间(未过期时)基础上顺延;`make_permanent` 清空过期时间并置次数 -1。
|
||
|
||
## 管理员下载:GET /admin/file/download?id=
|
||
|
||
下载原文件(**不消耗取件次数**);文件返回二进制流(支持 Range),文本分享返回 JSON(`data` 为文本内容)。
|
||
|
||
```bash
|
||
curl -s -OJ "http://localhost:8466/admin/file/download?id=42" -H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
## 文本预览:GET /admin/file/preview
|
||
|
||
仅文本分享可用(文件分享返回 400)。`maxChars` 截断长度(默认 4000,1~20000)。
|
||
|
||
```bash
|
||
curl -s "http://localhost:8466/admin/file/preview?id=41&maxChars=100" -H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"id": 41, "code": "8XQ2M", "name": "Text.txt", "type": "text",
|
||
"content": "你好,文件快传",
|
||
"length": 24, "previewLength": 24, "truncated": false,
|
||
"maxChars": 100, "max_chars": 100,
|
||
"created_at": "2025-06-01T12:00:00+08:00", "createdAt": "2025-06-01T12:00:00+08:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
```json
|
||
{ "code": 400, "msg": "仅文本分享支持预览" }
|
||
```
|
||
|
||
## 读取配置:GET /admin/config/get
|
||
|
||
返回运行时配置 KV(含默认值与管理端修改)。`admin_token` 恒返回空串(屏蔽);
|
||
`jwt_secret` 不下发;存储引擎为进程级单例,`_engine_hint` 提示引擎配置修改需重启。
|
||
26.9 新增键(需求 ①②③④⑩)一并返回:`background_url`、`footer_text`、`footer_beian`、
|
||
`notify_enabled`、`max_save_count`、`max_file_size` 等。
|
||
|
||
```json
|
||
{
|
||
"code": 200, "msg": "ok",
|
||
"data": {
|
||
"site_name": "文件快传",
|
||
"name": "文件快传",
|
||
"description": "开箱即用的文件快传系统",
|
||
"page_explain": "…", "keywords": "…",
|
||
"notify_title": "系统通知", "notify_content": "…", "notify_enabled": 1,
|
||
"logo_url": "",
|
||
"favicon_url": "",
|
||
"background_url": "", "footer_text": "", "footer_beian": "",
|
||
"openUpload": 1, "uploadSize": 10485760,
|
||
"max_file_size": 0, "max_save_count": 0,
|
||
"allowed_file_types": ["*"], "expireStyle": ["day","hour","minute","forever","count"],
|
||
"code_generate_type": "secret", "enableChunk": 1,
|
||
"uploadMinute": 1, "uploadCount": 10,
|
||
"errorMinute": 1, "errorCount": 10,
|
||
"loginCount": 5, "loginMinute": 15,
|
||
"max_save_seconds": 0, "storageLimit": 0,
|
||
"opacity": 0.9, "background": "", "showAdminAddr": 0, "robotsText": "User-agent: *\nDisallow: /",
|
||
"adminSessionExpire": 604800,
|
||
"storage_path": "", "local_storage_path": "/app/data",
|
||
"file_storage": "local",
|
||
"admin_token": "",
|
||
"_engine_hint": { "storage_backend": "local", "note": "存储引擎为进程级单例,修改存储引擎相关配置后需重启服务生效" }
|
||
}
|
||
}
|
||
```
|
||
|
||
## 存储引擎热切换:POST /admin/storage/switch(26.9)
|
||
|
||
运行时切换存储引擎,**无需重启**:
|
||
|
||
```bash
|
||
curl -s -X POST http://localhost:8466/admin/storage/switch \
|
||
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
||
-d '{"engine":"s3"}'
|
||
# 成功:{"code":200,"msg":"ok","data":{"ok":true,"engine":"s3"}}
|
||
# 失败:503 {"code":503,"msg":"存储引擎切换失败,已保持原引擎: …"}
|
||
```
|
||
|
||
- `engine` 仅接受 `local|s3|webdav`(400 中文错误)。
|
||
- 切换流程:用最新 KV 参数构建新引擎 → 健康检查 → 通过才替换当前引擎并持久化 `storage_engine`。
|
||
- 失败(构建/健康检查不过)返回 503,**原引擎与 KV 均保持不变**。
|
||
- 切到当前引擎为幂等操作(直接返回 200)。
|
||
- 旧文件按归属引擎(`file_codes.engine`)取回,切换后旧引擎文件仍可下载。
|
||
|
||
## 更新配置:PATCH /admin/config/update
|
||
|
||
部分更新(JSON 对象,未提供的键不变;表单亦可)。**PATCH 为主名,POST 为兼容别名**。
|
||
|
||
- 仅接受管理端可见键(见上响应键集合),未知键忽略。
|
||
- 数值型键自动转型:`openUpload`、`enableChunk`、`uploadSize`、`storageLimit`、限流四组、`max_save_seconds`、`adminSessionExpire`、`showAdminAddr`;26.9 新增 `max_save_count`、`max_file_size`、`notify_enabled`;`opacity` 为浮点。
|
||
- **26.9**:`site_domain`(站点对外域名)可经本端点设置,非法格式 400(仅 http/https、主机+端口、不带路径)。
|
||
- **26.9 引擎键**:`storage_engine` 不经本端点修改(走 `POST /admin/storage/switch`);引擎参数键
|
||
(`local_storage_path`、`webdav_url`、`webdav_root_path`、`webdav_username`、`webdav_password`、
|
||
`s3_endpoint_url`、`s3_region_name`、`s3_bucket_name`、`s3_access_key_id`、`s3_secret_access_key`、
|
||
`aws_session_token`、`s3_addressing_style`)可经本端点保存——保存后对应引擎实例缓存失效,
|
||
下次切换/构建生效;敏感键空串或 `******` 表示不修改。
|
||
- **26.9 schema 校验**(`settings.KVSchema`,越界一律 400,中文错误信息):
|
||
- 整型边界:`max_file_size` ≤ 10GiB(10737418240)、`max_save_count` ≤ 100000、`max_save_seconds` ≤ 31536000(365 天)、`notify_enabled` ∈ {0,1}、`uploadCount` 1~10000、`uploadMinute` 1~1440 等;
|
||
- 字符串长度:`background_url` ≤ 2048、`footer_text` ≤ 2000、`footer_beian` ≤ 128、`notify_title` ≤ 128、`notify_content` ≤ 2000 字符;
|
||
- 列表键 `expireStyle` / `allowed_file_types`:须为字符串数组(或逗号分隔串)且至少保留一项;
|
||
- 错误示例:`{"code":400,"msg":"max_file_size 必须是整数"}`、`{"code":400,"msg":"max_file_size 不能大于 10737418240"}`、`{"code":400,"msg":"footer_beian 长度不能超过 128 字符"}`、`{"code":400,"msg":"notify_enabled 不能大于 1"}`。
|
||
- `background_url` 协议白名单(需求 ①,防 `javascript:` 注入):仅 `http(s)://`、`data:image/*` 与站内相对路径(`/`开头);空串=清除背景。非法值 400:
|
||
`{"code":400,"msg":"background_url 仅支持 http(s) 地址、data:image 图片或站内相对路径"}`
|
||
- `admin_token`:明文密码自动哈希,**并轮换 `jwt_secret`(全部管理员令牌立即失效)**;空串忽略;已是哈希格式则原样保存。
|
||
- `adminSessionExpire` 须为 1~365 的整天秒数(86400 的整数倍),否则 400。
|
||
- `storageLimit` 不能小于 0。
|
||
- 修改限流/策略配置**立即生效**(无需重启:限流规则运行时同步,策略由上传链路每次实时读取);引擎相关(`file_storage`/`s3_*`/`webdav_*`/`storage_path`/`local_storage_path`)需重启。
|
||
|
||
```bash
|
||
curl -s -X PATCH http://localhost:8466/admin/config/update \
|
||
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
||
-d '{"site_name":"我的文件柜","uploadSize":52428800,"openUpload":1,"footer_beian":"京ICP备20240001号","max_file_size":10485760,"max_save_count":5}'
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "ok": true } }
|
||
```
|
||
|
||
```json
|
||
{ "code": 400, "msg": "adminSessionExpire 必须是 1 到 365 个整天" }
|
||
```
|
||
|
||
```json
|
||
{ "code": 400, "msg": "background_url 仅支持 http(s) 地址、data:image 图片或站内相对路径" }
|
||
```
|
||
|
||
## 修改管理员密码:PATCH /admin/settings/password
|
||
|
||
`PATCH` 或 `POST`。新密码 ≥8 位;成功后哈希保存并**轮换 `jwt_secret`,所有旧令牌失效(401)**,需重新登录。
|
||
|
||
```bash
|
||
curl -s -X PATCH http://localhost:8466/admin/settings/password \
|
||
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
|
||
-d '{"old_password":"admin12345","new_password":"new-pass-6789"}'
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "ok": true } }
|
||
```
|
||
|
||
```json
|
||
{ "code": 400, "msg": "新密码长度至少 8 位" }
|
||
```
|
||
|
||
```json
|
||
{ "code": 401, "msg": "旧密码错误" }
|
||
```
|
||
|
||
## 手动回收:POST /admin/recycle/run
|
||
|
||
**26.9**:手动触发一轮过期分享回收(定时循环之外的管理端入口)。回收范围:
|
||
时间已过期、次数已耗尽、创建时间超过 `retention_days` 的分享——删除记录并
|
||
连带删除存储对象(SHA512 去重开启时做引用计数,仍有其他分享引用的对象保留)。
|
||
|
||
```bash
|
||
curl -s -X POST "http://localhost:8466/admin/recycle/run" -H "Authorization: Bearer $TOKEN"
|
||
```
|
||
|
||
```json
|
||
{ "code": 200, "msg": "ok", "data": { "removed": 3 } }
|
||
```
|
||
|
||
相关配置键:`recycle_enabled`(定时开关)、`recycle_interval`(扫描间隔)、
|
||
`retention_days`(最长存储时长)、`dedup_enabled`(引用计数开关)。
|