Files
olons_server/internal/httpapi/manual_products.go
T

105 lines
3.2 KiB
Go

package httpapi
import (
"errors"
"net/http"
"strconv"
"strings"
"git.118im.com/im_team/olons_server/internal/mall"
"git.118im.com/im_team/olons_server/internal/store"
)
func (a *API) manualProducts(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
methodNotAllowed(w, r, http.MethodGet)
return
}
if a.mall == nil {
writeError(w, r, http.StatusServiceUnavailable, 90001, "SERVICE_UNAVAILABLE", "service unavailable", nil)
return
}
principal, ok := a.authenticateMember(w, r)
if !ok {
return
}
page, ok := optionalPositiveInt(w, r, "page")
if !ok {
writeMallError(w, r, mall.ErrPageInvalid)
return
}
pageSize, ok := optionalPositiveInt(w, r, "page_size")
if !ok {
writeMallError(w, r, mall.ErrPageSizeInvalid)
return
}
categoryID, ok := optionalNonNegativeInt64(r.URL.Query().Get("category_id"))
if !ok {
writeMallError(w, r, mall.ErrCategoryIDInvalid)
return
}
result, err := a.mall.Products(r.Context(), principal.TenantID, categoryID, page, pageSize)
if err != nil {
writeMallError(w, r, err)
return
}
writeSuccess(w, r, result)
}
func (a *API) manualProduct(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
methodNotAllowed(w, r, http.MethodGet)
return
}
if a.mall == nil {
writeError(w, r, http.StatusServiceUnavailable, 90001, "SERVICE_UNAVAILABLE", "service unavailable", nil)
return
}
productIDText := strings.Trim(strings.TrimPrefix(r.URL.Path, "/v1/manual-products/"), "/")
if productIDText == "" || strings.Contains(productIDText, "/") {
writeMallError(w, r, mall.ErrProductIDInvalid)
return
}
productID, err := strconv.ParseInt(productIDText, 10, 64)
if err != nil || productID <= 0 {
writeMallError(w, r, mall.ErrProductIDInvalid)
return
}
principal, ok := a.authenticateMember(w, r)
if !ok {
return
}
result, err := a.mall.Product(r.Context(), principal.TenantID, productID)
if err != nil {
writeMallError(w, r, err)
return
}
writeSuccess(w, r, result)
}
func optionalNonNegativeInt64(value string) (int64, bool) {
value = strings.TrimSpace(value)
if value == "" {
return 0, true
}
parsed, err := strconv.ParseInt(value, 10, 64)
return parsed, err == nil && parsed >= 0
}
func writeMallError(w http.ResponseWriter, r *http.Request, err error) {
switch {
case errors.Is(err, mall.ErrCategoryIDInvalid):
writeError(w, r, http.StatusBadRequest, 30000, "CATEGORY_ID_INVALID", "validation failed", map[string]any{"field": "category_id"})
case errors.Is(err, mall.ErrProductIDInvalid):
writeError(w, r, http.StatusBadRequest, 30000, "PRODUCT_ID_INVALID", "validation failed", map[string]any{"field": "product_id"})
case errors.Is(err, mall.ErrPageInvalid):
writeError(w, r, http.StatusBadRequest, 30000, "PAGE_INVALID", "validation failed", map[string]any{"field": "page"})
case errors.Is(err, mall.ErrPageSizeInvalid):
writeError(w, r, http.StatusBadRequest, 30000, "PAGE_SIZE_INVALID", "validation failed", map[string]any{"field": "page_size"})
case errors.Is(err, store.ErrResourceNotFound):
writeError(w, r, http.StatusNotFound, 30044, "PRODUCT_NOT_FOUND", "manual product not found", nil)
default:
writeError(w, r, http.StatusInternalServerError, 90000, reasonInternal, "internal error", nil)
}
}