26.9:版本号统一 + CI 精简 + 前端产物重建
CI 测试 / go vet + go test (push) Successful in 49s

- 全项目版本号统一:v3.x 迭代号(26.9/26.9/26.9/26.9 及裸 v2/v3)→ 26.9,
  覆盖 Go 注释 / 文档 / openapi.yaml / README×4 / 前端源码(80+ 处)
- v31_test.go 更名 custom_code_test.go;TestV2AccessorDefaults → TestKVAccessorDefaults
- docs/api/00-overview.md 更新日志合并为单条 26.9 条目(修复错位拼接)
- .goreleaser.yaml 头部注释与实际一致(Pro 2.18.1 / GITEA_TOKEN / semver tag 要求)
- CI:release-image.yml → ci.yml,仅保留 vet+test 门禁;
  镜像发布移交 GoReleaser Pro(原 build-push 的 tag 校验与 26.9 版本方案冲突,历史 9 次失败)
- 前端重建:server/web/dist 与 web-embed 同步(docs 文案嵌入更新)
This commit is contained in:
2026-09-08 03:16:51 +08:00
parent 27432218c4
commit 84df9996cb
122 changed files with 247 additions and 12268 deletions
+11 -11
View File
@@ -90,7 +90,7 @@ func (d *Deps) shareText(c *gin.Context) {
if !requireUploadLimit(c, d.Limiter) {
return
}
// v3.1 修复:JSON/表单/ultipart 统一绑定(form+json 双标签——此前仅 PostForm 时,
// 26.9 修复:JSON/表单/ultipart 统一绑定(form+json 双标签——此前仅 PostForm 时,
// JSON 提交会静默存成空文本并 200,取件页空白)。
var body struct {
Text string `json:"text" form:"text"`
@@ -120,7 +120,7 @@ func (d *Deps) shareText(c *gin.Context) {
if expireStyle == "" {
expireStyle = "day"
}
// v3.1:自定义提取码格式校验(4-8 位字母数字,空=随机)
// 26.9:自定义提取码格式校验(4-8 位字母数字,空=随机)
if err := validatePickupCode(body.Code); err != nil {
respondError(c, err)
return
@@ -153,11 +153,11 @@ func (d *Deps) shareText(c *gin.Context) {
ExpiredAt: exp.ExpiredAt,
ExpiredCount: exp.ExpiredCount,
UsedCount: exp.UsedCount,
Engine: d.Store.CurrentName(), // v3:归属引擎戳(文本也记录,保持一致性)
Engine: d.Store.CurrentName(), // 26.9:归属引擎戳(文本也记录,保持一致性)
}
err = d.DB.WithContext(ctx).Create(&fc).Error
}
err = mapCodeConflict(err) // v3.1:自定义码唯一索引冲突 → 友好 400
err = mapCodeConflict(err) // 26.9:自定义码唯一索引冲突 → 友好 400
releaseStorage(ctx, d.DB, token)
if err != nil {
auditRecordFailed(c, d.AuditSvc, "文本分享创建失败")
@@ -188,7 +188,7 @@ func (d *Deps) shareFile(c *gin.Context) {
return
}
origName := fh.Filename
// v2 需求 ④⑩:动态策略校验(max_file_size0=回落 uploadSize
// 26.9 需求 ④⑩:动态策略校验(max_file_size0=回落 uploadSize
if err := d.CurrentUploadPolicy().CheckSize(fh.Size); err != nil {
auditUploadEntry(c, "", origName, fh.Size, 0)
auditRecordFailed(c, d.AuditSvc, "大小超过限制")
@@ -205,7 +205,7 @@ func (d *Deps) shareFile(c *gin.Context) {
return
}
// v3.1:自定义提取码(落盘前校验,失败快速返回不占容量预留)
// 26.9:自定义提取码(落盘前校验,失败快速返回不占容量预留)
if err := validatePickupCode(c.PostForm("code")); err != nil {
auditUploadEntry(c, "", origName, fh.Size, 0)
auditRecordFailed(c, d.AuditSvc, "提取码非法")
@@ -257,10 +257,10 @@ func (d *Deps) shareFile(c *gin.Context) {
ExpiredAt: exp.ExpiredAt,
ExpiredCount: exp.ExpiredCount,
UsedCount: exp.UsedCount,
Engine: d.Store.CurrentName(), // v3:归属引擎戳(下载按此取回)
Engine: d.Store.CurrentName(), // 26.9:归属引擎戳(下载按此取回)
}
if err = d.DB.WithContext(ctx).Create(&fc).Error; err != nil {
err = mapCodeConflict(err) // v3.1
err = mapCodeConflict(err) // 26.9
// 记录创建失败:清理已落盘文件
_ = d.Store.DeleteFile(ctx, savePath)
}
@@ -273,7 +273,7 @@ func (d *Deps) shareFile(c *gin.Context) {
auditUploadEntry(c, "", origName, fh.Size, 0)
auditRecordFailed(c, d.AuditSvc, "文件保存失败")
if be, ok := err.(*apiError); ok && be.Status == http.StatusBadRequest {
respondError(c, err) // v3.1:提取码冲突等业务 400 原样透出
respondError(c, err) // 26.9:提取码冲突等业务 400 原样透出
} else {
respondError(c, mapStorageError(err))
}
@@ -544,7 +544,7 @@ func (d *Deps) serveFile(c *gin.Context, fc *model.FileCodes) {
savePath := fileSavePath(fc)
name := fc.Prefix + fc.Suffix
// v3:按文件归属引擎取回(切换引擎后旧文件仍可下载);空戳=历史数据回落当前引擎
// 26.9:按文件归属引擎取回(切换引擎后旧文件仍可下载);空戳=历史数据回落当前引擎
store, err := d.storeFor(fc.Engine)
if err != nil {
auditUploadEntry(c, fc.Code, name, fc.Size, 0)
@@ -597,7 +597,7 @@ func (d *Deps) serveFile(c *gin.Context, fc *model.FileCodes) {
}
auditUploadEntry(c, fc.Code, name, total, 0)
c.Status(status)
// v3.2:下载带宽限速(storage.ReadCloser → 限速 reader → c.Writer
// 26.9:下载带宽限速(storage.ReadCloser → 限速 reader → c.Writer
dlReader := middleware.WrapReadCloser(dl, d.Cfg.DownloadRate())
n, _ := io.Copy(c.Writer, dlReader)
middleware.AuditSet(c, func(e *audit.Entry) {