后台站点设计UIUX优化

This commit is contained in:
2026-09-19 04:14:13 +08:00
parent a8efb9ecef
commit 2b3d122e56
24 changed files with 2952 additions and 306 deletions

View File

@@ -230,3 +230,82 @@ func (h *Handlers) UploadBackground(c *gin.Context) {
out["url"] = url
c.JSON(http.StatusOK, out)
}
// UploadBrand 超管上传 Logo / Favicon,只落盘返回 URL,不写站点设置
func (h *Handlers) UploadBrand(c *gin.Context) {
slot := c.PostForm("slot")
if _, ok := service.NormalizeBrandSlot(slot); !ok {
c.JSON(http.StatusBadRequest, gin.H{"error": "请指定 logo_light、logo_dark 或 favicon"})
return
}
maxB := int64(service.BrandLogoMaxBytes)
if slot == service.BrandSlotFavicon {
maxB = service.BrandFaviconMaxBytes
}
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, maxB+4096)
fh, err := c.FormFile("file")
if err != nil {
var maxErr *http.MaxBytesError
if errors.As(err, &maxErr) {
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": brandTooLarge(slot)})
return
}
c.JSON(http.StatusBadRequest, gin.H{"error": "图片过大或格式不正确"})
return
}
if fh.Size > maxB {
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": brandTooLarge(slot)})
return
}
f, err := fh.Open()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "读取图片失败"})
return
}
defer f.Close()
url, err := h.Upload.SaveBrand(slot, f)
if err != nil {
var maxErr *http.MaxBytesError
if errors.As(err, &maxErr) {
c.JSON(http.StatusRequestEntityTooLarge, gin.H{"error": brandTooLarge(slot)})
return
}
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"url": url})
}
type brandFromMediaRequest struct {
AttachmentID uint `json:"attachment_id"`
Slot string `json:"slot"`
}
// UploadBrandFromMedia 把本人媒体库图片复制进品牌目录,不写站点设置
func (h *Handlers) UploadBrandFromMedia(c *gin.Context) {
var req brandFromMediaRequest
if err := c.ShouldBindJSON(&req); err != nil || req.AttachmentID == 0 {
c.JSON(http.StatusBadRequest, gin.H{"error": "请选择媒体库中的图片"})
return
}
claims := middleware.CurrentUser(c)
if claims == nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": "请先登录"})
return
}
url, err := h.Upload.CopyBrandFromMedia(claims.ID, req.AttachmentID, req.Slot)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"url": url})
}
func brandTooLarge(slot string) string {
if slot == service.BrandSlotFavicon {
return "Favicon 不能超过 512KB"
}
return "Logo 不能超过 2MB"
}