| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 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) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	msg := "操作成功" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	msg := "创建成功" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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 | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	message := "服务器内部错误" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	msg := "用户未登录或认证已过期" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	msg := "权限不足,无法访问此资源" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	msg := "请求的资源不存在" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	msg := "服务器内部错误" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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, | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 		Message:    "查询成功", | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 		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{}) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	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 = "未知状态" | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	response := interfaces.APIResponse{ | 
					
						
							|  |  |  |  | 		Success:   statusCode >= 200 && statusCode < 300, | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 		Message:   message, | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 		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, | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 		Message:   "请求参数验证失败", | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 		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) { | 
					
						
							| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | 	msg := "请求过于频繁,请稍后再试" | 
					
						
							| 
									
										
										
										
											2025-06-30 19:21:56 +08:00
										 |  |  |  | 	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) | 
					
						
							|  |  |  |  | } |