package httpapi import ( "encoding/json" "errors" "io" "log" "net/http" "github.com/gin-gonic/gin" "git.apinb.com/ops/license/internal/dashboard" "git.apinb.com/ops/license/internal/issuance" "git.apinb.com/ops/license/internal/subject" ) type pagination struct { Page int `json:"page"` PageSize int `json:"page_size"` Total int64 `json:"total"` } func writeData(c *gin.Context, status int, data any) { c.JSON(status, gin.H{"data": data}) } func writePage(c *gin.Context, data any, page, pageSize int, total int64) { c.JSON(http.StatusOK, gin.H{ "data": data, "pagination": pagination{ Page: page, PageSize: pageSize, Total: total, }, }) } func writeBadRequest(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"code": "bad_request", "message": "请求格式不正确"}) } func writeError(c *gin.Context, err error) { status := http.StatusInternalServerError code := "internal_error" message := "服务器内部错误" switch { case errors.Is(err, subject.ErrNotFound): status, code, message = http.StatusNotFound, "subject_not_found", "授权对象不存在" case errors.Is(err, issuance.ErrNotFound): status, code, message = http.StatusNotFound, "licence_not_found", "签发记录不存在" case errors.Is(err, subject.ErrDuplicate): status, code, message = http.StatusConflict, "subject_duplicate", "授权对象已存在" case errors.Is(err, subject.ErrHasLicences): status, code, message = http.StatusConflict, "subject_has_licences", "该授权对象已有签发记录,不能修改或删除" case errors.Is(err, subject.ErrInvalidInput): status, code, message = http.StatusUnprocessableEntity, "invalid_subject", "授权对象字段不合法" case errors.Is(err, issuance.ErrInvalidDates): status, code, message = http.StatusUnprocessableEntity, "invalid_licence_dates", "许可证日期不合法" case errors.Is(err, issuance.ErrInvalidQuota): status, code, message = http.StatusUnprocessableEntity, "invalid_licence_quota", "许可证配额不合法" case errors.Is(err, issuance.ErrPreviousMismatch): status, code, message = http.StatusUnprocessableEntity, "previous_licence_mismatch", "续期来源与授权对象不匹配" case errors.Is(err, issuance.ErrInvalidInput), errors.Is(err, dashboard.ErrInvalidInput): status, code, message = http.StatusUnprocessableEntity, "invalid_issuance", "签发参数不合法" } if status == http.StatusInternalServerError { log.Printf("HTTP internal error: %v", err) } c.JSON(status, gin.H{"code": code, "message": message}) } func decodeJSON(c *gin.Context, destination any) error { decoder := json.NewDecoder(c.Request.Body) decoder.DisallowUnknownFields() if err := decoder.Decode(destination); err != nil { return err } var trailing any if err := decoder.Decode(&trailing); !errors.Is(err, io.EOF) { if err == nil { return errors.New("JSON 包含多个顶层值") } return err } return nil }