This commit is contained in:
tamakyi
2026-10-19 15:23:11 +08:00
parent 86dc8384bc
commit e9fba8b9ed
84 changed files with 34468 additions and 5386 deletions
+38
View File
@@ -9,6 +9,7 @@ import (
"fmt"
"net/url"
"strconv"
"strings"
"time"
"github.com/pkg/errors"
@@ -22,6 +23,7 @@ import (
"github.com/tamakyi/TamaBox/internal/i18n"
"github.com/tamakyi/TamaBox/internal/imagecheck"
"github.com/tamakyi/TamaBox/internal/storage"
"github.com/tamakyi/TamaBox/internal/theme"
)
// Profile 账号设置页。按面板分区:
@@ -39,6 +41,14 @@ func Profile(ctx context.Context) {
ctx.Data["StrictnessLocked"] = true
}
ctx.Data["TagLimits"] = tagLimits()
// 主题:可选清单(顺序同 [theme] available)+ 当前选择。
// 当前值取原始存储值,非法/已下线主题归零为「跟随站点默认」,避免单选一个都不选中。
ctx.Data["Themes"] = theme.List()
if theme.IsAvailable(ctx.User.Theme) {
ctx.Data["CurrentTheme"] = strings.ToLower(strings.TrimSpace(ctx.User.Theme))
} else {
ctx.Data["CurrentTheme"] = ""
}
ctx.Data["ChatLimits"] = chatLimits()
InjectFeatureViews(ctx)
ctx.Success("user/profile")
@@ -64,6 +74,34 @@ func chatLimits() map[string]int {
}
}
// UpdateTheme 保存箱主选择的主题。只写 users.theme 一列,
// 与背景图/颜色等个性化设置互不影响(各自独立的表单入口)。
func UpdateTheme(ctx context.Context, f form.UpdateProfileTheme) {
if ctx.HasError() {
ctx.Success("user/profile")
return
}
slug := strings.ToLower(strings.TrimSpace(f.Theme))
// 白名单校验:既挡住拼写错误,也挡住把任意字符串拼进 <link href> 的路径穿越尝试。
// 用 flash + 重定向而不是原地渲染:本页数据由 Profile() 装配(可选主题清单等),
// 直接 Success 会渲染出缺数据的页面。
if slug != "" && !theme.IsAvailable(slug) {
ctx.SetErrorFlash(i18n.T(ctx.Lang(), "profile.theme.invalid"))
ctx.Redirect("/user/profile")
return
}
if err := db.Users.UpdateTheme(ctx.Request().Context(), ctx.User.ID, slug); err != nil {
logrus.WithContext(ctx.Request().Context()).WithError(err).Error("Failed to update theme")
ctx.SetInternalErrorFlash()
ctx.Redirect("/user/profile")
return
}
ctx.SetSuccessFlash(i18n.T(ctx.Lang(), "profile.theme.saved"))
ctx.Redirect("/user/profile")
}
func ProfileAPI(ctx context.Context) error {
return ctx.JSON(ctx.User)
}