105 lines
3.2 KiB
Go
105 lines
3.2 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.118im.com/im_team/im_workbench/internal/mall"
|
|
"git.118im.com/im_team/im_workbench/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)
|
|
}
|
|
}
|