Initial commit: Basic project structure and dependencies

This commit is contained in:
2025-06-30 19:21:56 +08:00
commit 03e615a8fd
50 changed files with 11664 additions and 0 deletions

View File

@@ -0,0 +1,260 @@
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 := "Success"
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 := "Created successfully"
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 := "Internal server error"
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 := "Unauthorized"
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 := "Forbidden"
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 := "Resource not found"
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 := "Internal server error"
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: "Success",
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{}) {
response := interfaces.APIResponse{
Success: statusCode >= 200 && statusCode < 300,
Message: http.StatusText(statusCode),
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: "Validation failed",
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 := "Too many requests"
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)
}