可靠性: 完善 R2 备份恢复与对象生命周期

This commit is contained in:
tamakyi
2026-11-05 08:41:55 +08:00
parent 3e7719f200
commit 937e688cfa
32 changed files with 4151 additions and 231 deletions
+17
View File
@@ -5,6 +5,7 @@
package user
import (
stdctx "context"
"encoding/json"
"fmt"
"net/url"
@@ -121,6 +122,17 @@ func UpdateProfile(ctx context.Context, f form.UpdateProfile) {
return
}
var uploadedProfileImages []string
profileSaved := false
defer func() {
if profileSaved || len(uploadedProfileImages) == 0 {
return
}
if err := db.R2DeleteTasks.EnqueueValues(stdctx.Background(), conf.Upload.ImageBucket, uploadedProfileImages); err != nil {
logrus.WithError(err).Error("Failed to enqueue uploaded profile image compensation")
}
}()
// 处理头像上传(强制 1:1,见 storage.UploadAvatarToS3)
avatarURL := currentUser.Avatar // 默认使用原值
avatarFile, avatarFileHeader, err := ctx.Request().FormFile("avatar")
@@ -146,6 +158,7 @@ func UpdateProfile(ctx context.Context, f form.UpdateProfile) {
logrus.WithContext(ctx.Request().Context()).WithError(err).Error("Failed to upload avatar")
} else {
avatarURL = uploadedURL
uploadedProfileImages = append(uploadedProfileImages, uploadedURL)
}
}
@@ -177,6 +190,7 @@ func UpdateProfile(ctx context.Context, f form.UpdateProfile) {
logrus.WithContext(ctx.Request().Context()).WithError(err).Error("Failed to upload background")
} else {
backgroundURL = uploadedURL
uploadedProfileImages = append(uploadedProfileImages, uploadedURL)
}
}
@@ -200,6 +214,7 @@ func UpdateProfile(ctx context.Context, f form.UpdateProfile) {
logrus.WithContext(ctx.Request().Context()).WithError(err).Error("Failed to upload QRbackgroundImage")
} else {
backgroundImageURL = uploadedURL
uploadedProfileImages = append(uploadedProfileImages, uploadedURL)
}
}
@@ -268,6 +283,7 @@ func UpdateProfile(ctx context.Context, f form.UpdateProfile) {
}
ctx.SetInternalErrorFlash()
} else if passwordChanged {
profileSaved = true
// 密码修改成功且其余资料也保存成功:强制登出重登。
// 先 Flush 清会话再写入 flash,保证提示能带到登录页显示。
ctx.Session.Flush()
@@ -275,6 +291,7 @@ func UpdateProfile(ctx context.Context, f form.UpdateProfile) {
ctx.Redirect("/login")
return
} else {
profileSaved = true
ctx.SetSuccessFlash(i18n.T(ctx.Lang(), "admin.flash.profileUpdated"))
}
ctx.Redirect("/user/profile")