26.9:直链下载 + 过期回收 + SHA512 去重 + 防盗链 + 媒体预览 + 文件夹上传提示
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
This commit is contained in:
2026-09-08 04:54:05 +08:00
parent 84df9996cb
commit 7a9015aad0
25 changed files with 1259 additions and 15 deletions
+43
View File
@@ -168,6 +168,14 @@ paths:
uploadMinute: { type: integer, default: 1 }
upload_rate: { type: integer, format: int64, default: 0, description: '26.9 上行带宽字节/秒;0=不限速' }
download_rate: { type: integer, format: int64, default: 0, description: '26.9 下行带宽字节/秒;0=不限速' }
recycle_enabled: { type: integer, enum: [0, 1], default: 1, description: '26.9 过期分享自动回收开关' }
recycle_interval: { type: integer, format: int64, default: 1800, description: '26.9 回收扫描间隔秒(60~86400' }
retention_days: { type: integer, format: int64, default: 0, description: '26.9 最长存储时长天(0~36500=不限制)' }
dedup_enabled: { type: integer, enum: [0, 1], default: 1, description: '26.9 SHA512 内容去重开关' }
direct_download: { type: integer, enum: [0, 1], default: 1, description: '26.9 对象存储直链下载开关' }
direct_link_expire: { type: integer, format: int64, default: 900, description: '26.9 直链签名有效期秒(60~3600' }
hotlink_enabled: { type: integer, enum: [0, 1], default: 0, description: '26.9 下载防盗链开关' }
hotlink_whitelist: { type: string, maxLength: 2048, default: '', description: '26.9 防盗链白名单(逗号分隔域名,支持 *.example.com' }
allowed_file_types: { type: string, default: '*' }
openUpload: { type: boolean, default: true }
enableChunk: { type: boolean, default: false }
@@ -1379,6 +1387,14 @@ paths:
uploadMinute: { type: integer }
upload_rate: { type: integer, format: int64, description: '26.9 上行带宽字节/秒;0=不限速' }
download_rate: { type: integer, format: int64, description: '26.9 下行带宽字节/秒;0=不限速' }
recycle_enabled: { type: integer, enum: [0, 1], description: '26.9 过期分享自动回收开关' }
recycle_interval: { type: integer, format: int64, description: '26.9 回收扫描间隔秒(60~86400' }
retention_days: { type: integer, format: int64, description: '26.9 最长存储时长天(0~3650' }
dedup_enabled: { type: integer, enum: [0, 1], description: '26.9 SHA512 内容去重开关' }
direct_download: { type: integer, enum: [0, 1], description: '26.9 对象存储直链下载开关' }
direct_link_expire: { type: integer, format: int64, description: '26.9 直链签名有效期秒(60~3600' }
hotlink_enabled: { type: integer, enum: [0, 1], description: '26.9 下载防盗链开关' }
hotlink_whitelist: { type: string, maxLength: 2048, description: '26.9 防盗链白名单' }
admin_token: { type: string, example: '' }
_engine_hint:
type: object
@@ -1529,6 +1545,33 @@ paths:
"401": { $ref: "#/components/responses/Unauthorized" }
"503": { $ref: "#/components/responses/ServiceUnavailable" }
/admin/recycle/run:
post:
tags: [admin]
summary: 手动触发一轮过期回收(26.9
description: |
回收时间已过期、次数已耗尽、创建时间超过 retention_days 的分享:
删除记录并连带删除存储对象(dedup_enabled 开启时做引用计数,
仍有其他分享引用的对象保留)。返回本轮回收条数。
operationId: adminRecycleRun
security:
- bearerAuth: []
responses:
"200":
description: 回收完成
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Envelope'
- type: object
properties:
data:
type: object
properties:
removed: { type: integer, description: 本轮回收条数 }
"401": { $ref: '#/components/responses/Unauthorized' }
/admin/settings/password:
patch:
tags: [管理后台]