62 lines
1.8 KiB
Go
62 lines
1.8 KiB
Go
package integration
|
|
|
|
import (
|
|
"bytes"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"cmautobuy/admin/config"
|
|
"cmautobuy/admin/service"
|
|
)
|
|
|
|
const catalogMaxBody = 5 << 20
|
|
|
|
type Handler struct{ db *sql.DB }
|
|
|
|
// Register 只挂载第三方目录接口,不复用 Client 或网页登录中间件。
|
|
func Register(r *gin.Engine, db *sql.DB, cfg config.CatalogIntegrationConfig) {
|
|
h := &Handler{db: db}
|
|
g := r.Group("/api/v1/integrations/catalog", RequireCatalogToken(cfg))
|
|
g.POST("/batches", h.CreateBatch)
|
|
}
|
|
|
|
func (h *Handler) CreateBatch(c *gin.Context) {
|
|
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, catalogMaxBody)
|
|
raw, err := io.ReadAll(c.Request.Body)
|
|
if err != nil {
|
|
if _, ok := err.(*http.MaxBytesError); ok {
|
|
integrationError(c, 413, "PAYLOAD_TOO_LARGE", "请求体不能超过 5 MB", false, nil)
|
|
return
|
|
}
|
|
integrationError(c, 400, "INVALID_BODY", "读取请求失败", false, nil)
|
|
return
|
|
}
|
|
var req service.CatalogBatchRequest
|
|
dec := json.NewDecoder(bytes.NewReader(raw))
|
|
dec.DisallowUnknownFields()
|
|
if err = dec.Decode(&req); err != nil {
|
|
integrationError(c, 400, "INVALID_JSON", "请求体不是合法的商品目录 JSON", false, nil)
|
|
return
|
|
}
|
|
if dec.Decode(&struct{}{}) != io.EOF {
|
|
integrationError(c, 400, "INVALID_JSON", "请求体只能包含一个 JSON 对象", false, nil)
|
|
return
|
|
}
|
|
resp, err := service.ImportCatalogBatch(h.db, integrationSource(c), req, raw)
|
|
if err != nil {
|
|
var catalogErr *service.CatalogError
|
|
if errors.As(err, &catalogErr) {
|
|
integrationError(c, catalogErr.Status, catalogErr.Code, catalogErr.Message, catalogErr.Retryable, catalogErr.Details)
|
|
return
|
|
}
|
|
integrationError(c, 500, "INTERNAL_ERROR", "商品目录批次处理失败", true, nil)
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, resp)
|
|
}
|