refactor(api): better type safety, split homepage override apis, fixed favicon api docs

This commit is contained in:
yusing
2025-08-16 19:57:14 +08:00
parent 1e78a0a0a0
commit 90efa36193
12 changed files with 1013 additions and 582 deletions

View File

@@ -2,7 +2,6 @@ package homepageapi
import (
"encoding/json"
"errors"
"net/http"
"github.com/gin-gonic/gin"
@@ -10,13 +9,6 @@ import (
"github.com/yusing/go-proxy/internal/homepage"
)
const (
HomepageOverrideItem = "item"
HomepageOverrideItemsBatch = "items_batch"
HomepageOverrideCategoryOrder = "category_order"
HomepageOverrideItemVisible = "item_visible"
)
type (
HomepageOverrideItemParams struct {
Which string `json:"which"`
@@ -35,76 +27,119 @@ type (
} // @name HomepageOverrideItemVisibleParams
)
type SetHomePageOverridesRequest struct {
What string `json:"what" validate:"required,oneof=item items_batch category_order item_visible"`
Value any `json:"value" validate:"required" swaggerType:"object"`
}
// @x-id "set"
// @x-id "set-item"
// @BasePath /api/v1
// @Summary Set homepage overrides
// @Description Set homepage overrides
// @Summary Override single homepage item
// @Description Override single homepage item.
// @Tags homepage
// @Accept json
// @Accept json
// @Produce json
// @Param request body SetHomePageOverridesRequest{value=HomepageOverrideItemParams} true "Override single item"
// @Param request body SetHomePageOverridesRequest{value=HomepageOverrideItemsBatchParams} true "Override multiple items"
// @Param request body SetHomePageOverridesRequest{value=HomepageOverrideCategoryOrderParams} true "Override category order"
// @Param request body SetHomePageOverridesRequest{value=HomepageOverrideItemVisibleParams} true "Override item visibility"
// @Param request body HomepageOverrideItemParams true "Override single item"
// @Success 200 {object} apitypes.SuccessResponse
// @Failure 400 {object} apitypes.ErrorResponse
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /homepage/set [post]
func Set(c *gin.Context) {
var request SetHomePageOverridesRequest
if err := c.ShouldBindJSON(&request); err != nil {
// @Router /homepage/set/item [post]
func SetItem(c *gin.Context) {
var params HomepageOverrideItemParams
if err := c.ShouldBindJSON(&params); err != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
return
}
data, err := c.GetRawData()
if err != nil {
c.Error(apitypes.InternalServerError(err, "failed to get raw data"))
return
}
overrides := homepage.GetOverrideConfig()
switch request.What {
case HomepageOverrideItem:
var params HomepageOverrideItemParams
if err := json.Unmarshal(data, &params); err != nil {
c.Error(apitypes.InternalServerError(err, "failed to unmarshal data"))
overrides.OverrideItem(params.Which, &params.Value)
c.JSON(http.StatusOK, apitypes.Success("success"))
}
// @x-id "set-items-batch"
// @BasePath /api/v1
// @Summary Override multiple homepage items
// @Description Override multiple homepage items.
// @Tags homepage
// @Accept json
// @Produce json
// @Param request body HomepageOverrideItemsBatchParams true "Override multiple items"
// @Success 200 {object} apitypes.SuccessResponse
// @Failure 400 {object} apitypes.ErrorResponse
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /homepage/set/items_batch [post]
func SetItemsBatch(c *gin.Context) {
var params HomepageOverrideItemsBatchParams
if err := c.ShouldBindJSON(&params); err != nil {
data, derr := c.GetRawData()
if derr != nil {
c.Error(apitypes.InternalServerError(derr, "failed to get raw data"))
return
}
overrides.OverrideItem(params.Which, &params.Value)
case HomepageOverrideItemsBatch:
var params HomepageOverrideItemsBatchParams
if err := json.Unmarshal(data, &params); err != nil {
c.Error(apitypes.InternalServerError(err, "failed to unmarshal data"))
if uerr := json.Unmarshal(data, &params); uerr != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", uerr))
return
}
overrides.OverrideItems(params.Value)
case HomepageOverrideItemVisible: // POST /v1/item_visible [a,b,c], false => hide a, b, c
var params HomepageOverrideItemVisibleParams
if err := json.Unmarshal(data, &params); err != nil {
c.Error(apitypes.InternalServerError(err, "failed to unmarshal data"))
}
overrides := homepage.GetOverrideConfig()
overrides.OverrideItems(params.Value)
c.JSON(http.StatusOK, apitypes.Success("success"))
}
// @x-id "set-item-visible"
// @BasePath /api/v1
// @Summary Set homepage item visibility
// @Description POST list of item ids and visibility value.
// @Tags homepage
// @Accept json
// @Produce json
// @Param request body HomepageOverrideItemVisibleParams true "Set item visibility"
// @Success 200 {object} apitypes.SuccessResponse
// @Failure 400 {object} apitypes.ErrorResponse
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /homepage/set/item_visible [post]
func SetItemVisible(c *gin.Context) {
var params HomepageOverrideItemVisibleParams
if err := c.ShouldBindJSON(&params); err != nil {
data, derr := c.GetRawData()
if derr != nil {
c.Error(apitypes.InternalServerError(derr, "failed to get raw data"))
return
}
if params.Value {
overrides.UnhideItems(params.Which)
} else {
overrides.HideItems(params.Which)
}
case HomepageOverrideCategoryOrder:
var params HomepageOverrideCategoryOrderParams
if err := json.Unmarshal(data, &params); err != nil {
c.Error(apitypes.InternalServerError(err, "failed to unmarshal data"))
if uerr := json.Unmarshal(data, &params); uerr != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", uerr))
return
}
overrides.SetCategoryOrder(params.Which, params.Value)
default: // won't happen
c.JSON(http.StatusBadRequest, apitypes.Error("invalid what", errors.New("invalid what")))
return
}
overrides := homepage.GetOverrideConfig()
if params.Value {
overrides.UnhideItems(params.Which)
} else {
overrides.HideItems(params.Which)
}
c.JSON(http.StatusOK, apitypes.Success("success"))
}
// @x-id "set-category-order"
// @BasePath /api/v1
// @Summary Set homepage category order
// @Description Set homepage category order.
// @Tags homepage
// @Accept json
// @Produce json
// @Param request body HomepageOverrideCategoryOrderParams true "Override category order"
// @Success 200 {object} apitypes.SuccessResponse
// @Failure 400 {object} apitypes.ErrorResponse
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /homepage/set/category_order [post]
func SetCategoryOrder(c *gin.Context) {
var params HomepageOverrideCategoryOrderParams
if err := c.ShouldBindJSON(&params); err != nil {
data, derr := c.GetRawData()
if derr != nil {
c.Error(apitypes.InternalServerError(derr, "failed to get raw data"))
return
}
if uerr := json.Unmarshal(data, &params); uerr != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", uerr))
return
}
}
overrides := homepage.GetOverrideConfig()
overrides.SetCategoryOrder(params.Which, params.Value)
c.JSON(http.StatusOK, apitypes.Success("success"))
}