Files
license/internal/httpapi/response.go
2026-07-31 16:59:55 +08:00

89 lines
2.9 KiB
Go

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
}