feat: 交付官方 Docker 运行时,外观改背景图并下线自定义 CSS/JS
站点/后台分轨背景与用户列表排序一并落地;生产 CORS 改走 SITE_URL,健康检查带版本号。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/freefire/jiang13-bbs/middleware"
|
||||
"github.com/freefire/jiang13-bbs/realtime"
|
||||
"github.com/freefire/jiang13-bbs/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -165,3 +166,67 @@ func (h *Handlers) DeleteAttachment(c *gin.Context) {
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"ok": true})
|
||||
}
|
||||
|
||||
// UploadBackground 超管上传站点背景图(JPEG/PNG/WebP),并立即绑定前台或后台
|
||||
func (h *Handlers) UploadBackground(c *gin.Context) {
|
||||
surface, ok := service.NormalizeBgSurface(c.PostForm("surface"))
|
||||
if !ok {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "请指定前台或后台(surface=site|admin)"})
|
||||
return
|
||||
}
|
||||
|
||||
limit := int64(service.BackgroundMaxBytes + 4096)
|
||||
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, limit)
|
||||
|
||||
fh, err := c.FormFile("file")
|
||||
if err != nil {
|
||||
var maxErr *http.MaxBytesError
|
||||
if errors.As(err, &maxErr) {
|
||||
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": "背景图不能超过 8MB"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "图片过大或格式不正确"})
|
||||
return
|
||||
}
|
||||
if fh.Size > service.BackgroundMaxBytes {
|
||||
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": "背景图不能超过 8MB"})
|
||||
return
|
||||
}
|
||||
f, err := fh.Open()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "读取图片失败"})
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
url, err := h.Upload.SaveBackground(f)
|
||||
if err != nil {
|
||||
var maxErr *http.MaxBytesError
|
||||
if errors.As(err, &maxErr) {
|
||||
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": "背景图不能超过 8MB"})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.applyBgURL(surface, url); err != nil {
|
||||
writeBgSettingError(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
saved, err := h.Setting.Public()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "获取站点设置失败"})
|
||||
return
|
||||
}
|
||||
payload := settingsPayload(saved)
|
||||
h.Hub.BroadcastAll(realtime.Envelope{
|
||||
Type: realtime.EventSettingsChanged,
|
||||
Data: payload,
|
||||
})
|
||||
out := settingsPayload(saved)
|
||||
out["ok"] = true
|
||||
out["url"] = url
|
||||
c.JSON(http.StatusOK, out)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user