287 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			287 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package http
 | ||
| 
 | ||
| import (
 | ||
| 	"math"
 | ||
| 	"net/http"
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"tyapi-server/internal/shared/interfaces"
 | ||
| 
 | ||
| 	"github.com/gin-gonic/gin"
 | ||
| )
 | ||
| 
 | ||
| // ResponseBuilder 响应构建器实现
 | ||
| type ResponseBuilder struct{}
 | ||
| 
 | ||
| // NewResponseBuilder 创建响应构建器
 | ||
| func NewResponseBuilder() interfaces.ResponseBuilder {
 | ||
| 	return &ResponseBuilder{}
 | ||
| }
 | ||
| 
 | ||
| // Success 成功响应
 | ||
| func (r *ResponseBuilder) Success(c *gin.Context, data interface{}, message ...string) {
 | ||
| 	msg := "操作成功"
 | ||
| 	if len(message) > 0 && message[0] != "" {
 | ||
| 		msg = message[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   true,
 | ||
| 		Message:   msg,
 | ||
| 		Data:      data,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusOK, response)
 | ||
| }
 | ||
| 
 | ||
| // Created 创建成功响应
 | ||
| func (r *ResponseBuilder) Created(c *gin.Context, data interface{}, message ...string) {
 | ||
| 	msg := "创建成功"
 | ||
| 	if len(message) > 0 && message[0] != "" {
 | ||
| 		msg = message[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   true,
 | ||
| 		Message:   msg,
 | ||
| 		Data:      data,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusCreated, response)
 | ||
| }
 | ||
| 
 | ||
| // Error 错误响应
 | ||
| func (r *ResponseBuilder) Error(c *gin.Context, err error) {
 | ||
| 	// 根据错误类型确定状态码
 | ||
| 	statusCode := http.StatusInternalServerError
 | ||
| 	message := "服务器内部错误"
 | ||
| 	errorDetail := err.Error()
 | ||
| 
 | ||
| 	// 这里可以根据不同的错误类型设置不同的状态码
 | ||
| 	// 例如:ValidationError -> 400, NotFoundError -> 404, etc.
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   message,
 | ||
| 		Errors:    errorDetail,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(statusCode, response)
 | ||
| }
 | ||
| 
 | ||
| // BadRequest 400错误响应
 | ||
| func (r *ResponseBuilder) BadRequest(c *gin.Context, message string, errors ...interface{}) {
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   message,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	if len(errors) > 0 {
 | ||
| 		response.Errors = errors[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusBadRequest, response)
 | ||
| }
 | ||
| 
 | ||
| // Unauthorized 401错误响应
 | ||
| func (r *ResponseBuilder) Unauthorized(c *gin.Context, message ...string) {
 | ||
| 	msg := "用户未登录或认证已过期"
 | ||
| 	if len(message) > 0 && message[0] != "" {
 | ||
| 		msg = message[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   msg,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusUnauthorized, response)
 | ||
| }
 | ||
| 
 | ||
| // Forbidden 403错误响应
 | ||
| func (r *ResponseBuilder) Forbidden(c *gin.Context, message ...string) {
 | ||
| 	msg := "权限不足,无法访问此资源"
 | ||
| 	if len(message) > 0 && message[0] != "" {
 | ||
| 		msg = message[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   msg,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusForbidden, response)
 | ||
| }
 | ||
| 
 | ||
| // NotFound 404错误响应
 | ||
| func (r *ResponseBuilder) NotFound(c *gin.Context, message ...string) {
 | ||
| 	msg := "请求的资源不存在"
 | ||
| 	if len(message) > 0 && message[0] != "" {
 | ||
| 		msg = message[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   msg,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusNotFound, response)
 | ||
| }
 | ||
| 
 | ||
| // Conflict 409错误响应
 | ||
| func (r *ResponseBuilder) Conflict(c *gin.Context, message string) {
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   message,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusConflict, response)
 | ||
| }
 | ||
| 
 | ||
| // InternalError 500错误响应
 | ||
| func (r *ResponseBuilder) InternalError(c *gin.Context, message ...string) {
 | ||
| 	msg := "服务器内部错误"
 | ||
| 	if len(message) > 0 && message[0] != "" {
 | ||
| 		msg = message[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   msg,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusInternalServerError, response)
 | ||
| }
 | ||
| 
 | ||
| // Paginated 分页响应
 | ||
| func (r *ResponseBuilder) Paginated(c *gin.Context, data interface{}, pagination interfaces.PaginationMeta) {
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:    true,
 | ||
| 		Message:    "查询成功",
 | ||
| 		Data:       data,
 | ||
| 		Pagination: &pagination,
 | ||
| 		RequestID:  r.getRequestID(c),
 | ||
| 		Timestamp:  time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusOK, response)
 | ||
| }
 | ||
| 
 | ||
| // getRequestID 从上下文获取请求ID
 | ||
| func (r *ResponseBuilder) getRequestID(c *gin.Context) string {
 | ||
| 	if requestID, exists := c.Get("request_id"); exists {
 | ||
| 		if id, ok := requestID.(string); ok {
 | ||
| 			return id
 | ||
| 		}
 | ||
| 	}
 | ||
| 	return ""
 | ||
| }
 | ||
| 
 | ||
| // BuildPagination 构建分页元数据
 | ||
| func BuildPagination(page, pageSize int, total int64) interfaces.PaginationMeta {
 | ||
| 	totalPages := int(math.Ceil(float64(total) / float64(pageSize)))
 | ||
| 
 | ||
| 	if totalPages < 1 {
 | ||
| 		totalPages = 1
 | ||
| 	}
 | ||
| 
 | ||
| 	return interfaces.PaginationMeta{
 | ||
| 		Page:       page,
 | ||
| 		PageSize:   pageSize,
 | ||
| 		Total:      total,
 | ||
| 		TotalPages: totalPages,
 | ||
| 		HasNext:    page < totalPages,
 | ||
| 		HasPrev:    page > 1,
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // CustomResponse 自定义响应
 | ||
| func (r *ResponseBuilder) CustomResponse(c *gin.Context, statusCode int, data interface{}) {
 | ||
| 	var message string
 | ||
| 	switch statusCode {
 | ||
| 	case http.StatusOK:
 | ||
| 		message = "请求成功"
 | ||
| 	case http.StatusCreated:
 | ||
| 		message = "创建成功"
 | ||
| 	case http.StatusNoContent:
 | ||
| 		message = "无内容"
 | ||
| 	case http.StatusBadRequest:
 | ||
| 		message = "请求参数错误"
 | ||
| 	case http.StatusUnauthorized:
 | ||
| 		message = "认证失败"
 | ||
| 	case http.StatusForbidden:
 | ||
| 		message = "权限不足"
 | ||
| 	case http.StatusNotFound:
 | ||
| 		message = "资源不存在"
 | ||
| 	case http.StatusConflict:
 | ||
| 		message = "资源冲突"
 | ||
| 	case http.StatusTooManyRequests:
 | ||
| 		message = "请求过于频繁"
 | ||
| 	case http.StatusInternalServerError:
 | ||
| 		message = "服务器内部错误"
 | ||
| 	default:
 | ||
| 		message = "未知状态"
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   statusCode >= 200 && statusCode < 300,
 | ||
| 		Message:   message,
 | ||
| 		Data:      data,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(statusCode, response)
 | ||
| }
 | ||
| 
 | ||
| // ValidationError 验证错误响应
 | ||
| func (r *ResponseBuilder) ValidationError(c *gin.Context, errors interface{}) {
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   "请求参数验证失败",
 | ||
| 		Errors:    errors,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusUnprocessableEntity, response)
 | ||
| }
 | ||
| 
 | ||
| // TooManyRequests 限流错误响应
 | ||
| func (r *ResponseBuilder) TooManyRequests(c *gin.Context, message ...string) {
 | ||
| 	msg := "请求过于频繁,请稍后再试"
 | ||
| 	if len(message) > 0 && message[0] != "" {
 | ||
| 		msg = message[0]
 | ||
| 	}
 | ||
| 
 | ||
| 	response := interfaces.APIResponse{
 | ||
| 		Success:   false,
 | ||
| 		Message:   msg,
 | ||
| 		RequestID: r.getRequestID(c),
 | ||
| 		Timestamp: time.Now().Unix(),
 | ||
| 		Meta: map[string]interface{}{
 | ||
| 			"retry_after": "60s",
 | ||
| 		},
 | ||
| 	}
 | ||
| 
 | ||
| 	c.JSON(http.StatusTooManyRequests, response)
 | ||
| }
 |