| 
									
										
										
										
											2025-07-02 16:17:59 +08:00
										 |  |  |  | # TYAPI Server API 开发规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🏗️ 项目架构概览 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 本项目采用 **DDD(领域驱动设计)** + **Clean Architecture** + **事件驱动架构**,基于 Gin 框架构建的企业级后端 API 服务。 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📋 目录结构规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | internal/ | 
					
						
							|  |  |  |  | ├── domains/                    # 领域层 | 
					
						
							|  |  |  |  | │   └── user/                  # 用户领域 | 
					
						
							|  |  |  |  | │       ├── dto/               # 数据传输对象 | 
					
						
							|  |  |  |  | │       ├── entities/          # 实体 | 
					
						
							|  |  |  |  | │       ├── events/            # 领域事件 | 
					
						
							|  |  |  |  | │       ├── handlers/          # HTTP处理器 | 
					
						
							|  |  |  |  | │       ├── repositories/      # 仓储接口实现 | 
					
						
							|  |  |  |  | │       ├── routes/            # 路由配置 | 
					
						
							|  |  |  |  | │       ├── services/          # 领域服务 | 
					
						
							|  |  |  |  | │       └── validators/        # 验证器 | 
					
						
							|  |  |  |  | ├── shared/                    # 共享基础设施 | 
					
						
							|  |  |  |  | │   ├── interfaces/            # 接口定义 | 
					
						
							|  |  |  |  | │   ├── middleware/            # 中间件 | 
					
						
							|  |  |  |  | │   ├── http/                  # HTTP基础组件 | 
					
						
							|  |  |  |  | │   └── ... | 
					
						
							|  |  |  |  | └── config/                    # 配置管理 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🎯 业务分层架构 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 控制器层 (Handlers) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/domains/user/handlers/user_handler.go | 
					
						
							|  |  |  |  | type UserHandler struct { | 
					
						
							|  |  |  |  |     userService *services.UserService     // 注入领域服务 | 
					
						
							|  |  |  |  |     response    interfaces.ResponseBuilder // 统一响应构建器 | 
					
						
							|  |  |  |  |     validator   interfaces.RequestValidator // 请求验证器 | 
					
						
							|  |  |  |  |     logger      *zap.Logger               // 结构化日志 | 
					
						
							|  |  |  |  |     jwtAuth     *middleware.JWTAuthMiddleware // JWT认证 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 标准CRUD处理器方法 | 
					
						
							|  |  |  |  | func (h *UserHandler) Create(c *gin.Context) { | 
					
						
							|  |  |  |  |     var req dto.CreateUserRequest | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 1. 请求验证 | 
					
						
							|  |  |  |  |     if err := h.validator.BindAndValidate(c, &req); err != nil { | 
					
						
							|  |  |  |  |         return // 验证器已处理响应 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 2. 调用领域服务 | 
					
						
							|  |  |  |  |     user, err := h.userService.Create(c.Request.Context(), &req) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         h.logger.Error("Failed to create user", zap.Error(err)) | 
					
						
							|  |  |  |  |         h.response.BadRequest(c, err.Error()) | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 3. 统一响应格式 | 
					
						
							|  |  |  |  |     response := dto.FromEntity(user) | 
					
						
							|  |  |  |  |     h.response.Created(c, response, "User created successfully") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 服务层 (Services) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/domains/user/services/user_service.go | 
					
						
							|  |  |  |  | type UserService struct { | 
					
						
							|  |  |  |  |     repo     *repositories.UserRepository  // 数据访问 | 
					
						
							|  |  |  |  |     eventBus interfaces.EventBus          // 事件总线 | 
					
						
							|  |  |  |  |     logger   *zap.Logger                  // 日志 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (s *UserService) Create(ctx context.Context, req *dto.CreateUserRequest) (*entities.User, error) { | 
					
						
							|  |  |  |  |     // 1. 业务规则验证 | 
					
						
							|  |  |  |  |     if err := s.validateCreateUser(req); err != nil { | 
					
						
							|  |  |  |  |         return nil, err | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 2. 实体创建 | 
					
						
							|  |  |  |  |     user := entities.NewUser(req.Username, req.Email, req.Password) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 3. 数据持久化 | 
					
						
							|  |  |  |  |     if err := s.repo.Create(ctx, user); err != nil { | 
					
						
							|  |  |  |  |         return nil, err | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 4. 发布领域事件 | 
					
						
							|  |  |  |  |     event := events.NewUserCreatedEvent(user.ID, user.Username, user.Email) | 
					
						
							|  |  |  |  |     s.eventBus.PublishAsync(ctx, event) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return user, nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 仓储层 (Repositories) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/domains/user/repositories/user_repository.go | 
					
						
							|  |  |  |  | type UserRepository struct { | 
					
						
							|  |  |  |  |     db     *gorm.DB                    // 数据库连接 | 
					
						
							|  |  |  |  |     cache  interfaces.CacheService    // 缓存服务 | 
					
						
							|  |  |  |  |     logger *zap.Logger               // 日志 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (r *UserRepository) Create(ctx context.Context, user *entities.User) error { | 
					
						
							|  |  |  |  |     // 使用事务确保数据一致性 | 
					
						
							|  |  |  |  |     return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { | 
					
						
							|  |  |  |  |         if err := tx.Create(user).Error; err != nil { | 
					
						
							|  |  |  |  |             return err | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 清除相关缓存 | 
					
						
							|  |  |  |  |         r.cache.Delete(ctx, fmt.Sprintf("user:count")) | 
					
						
							|  |  |  |  |         return nil | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. DTO 层 (数据传输对象) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/domains/user/dto/user_dto.go | 
					
						
							|  |  |  |  | type CreateUserRequest struct { | 
					
						
							|  |  |  |  |     Username        string `json:"username" binding:"required,min=3,max=50" validate:"username"` | 
					
						
							|  |  |  |  |     Email          string `json:"email" binding:"required,email" validate:"email"` | 
					
						
							|  |  |  |  |     Password       string `json:"password" binding:"required,min=8" validate:"password"` | 
					
						
							|  |  |  |  |     DisplayName    string `json:"display_name" binding:"max=100"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | type UserResponse struct { | 
					
						
							|  |  |  |  |     ID          string    `json:"id"` | 
					
						
							|  |  |  |  |     Username    string    `json:"username"` | 
					
						
							|  |  |  |  |     Email       string    `json:"email"` | 
					
						
							|  |  |  |  |     DisplayName string    `json:"display_name"` | 
					
						
							|  |  |  |  |     CreatedAt   time.Time `json:"created_at"` | 
					
						
							|  |  |  |  |     UpdatedAt   time.Time `json:"updated_at"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 实体转换函数 | 
					
						
							|  |  |  |  | func FromEntity(user *entities.User) *UserResponse { | 
					
						
							|  |  |  |  |     return &UserResponse{ | 
					
						
							|  |  |  |  |         ID:          user.ID, | 
					
						
							|  |  |  |  |         Username:    user.Username, | 
					
						
							|  |  |  |  |         Email:       user.Email, | 
					
						
							|  |  |  |  |         DisplayName: user.DisplayName, | 
					
						
							|  |  |  |  |         CreatedAt:   user.CreatedAt, | 
					
						
							|  |  |  |  |         UpdatedAt:   user.UpdatedAt, | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🛣️ 路由配置规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. DDD 领域路由设计模式 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/domains/user/routes/user_routes.go | 
					
						
							|  |  |  |  | type UserRoutes struct { | 
					
						
							|  |  |  |  |     handler *handlers.UserHandler | 
					
						
							|  |  |  |  |     jwtAuth *middleware.JWTAuthMiddleware | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (r *UserRoutes) RegisterRoutes(router *gin.Engine) { | 
					
						
							|  |  |  |  |     // API版本组 | 
					
						
							|  |  |  |  |     v1 := router.Group("/api/v1") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 🏢 用户域路由组 - 按域名组织 | 
					
						
							|  |  |  |  |     users := v1.Group("/users") | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         // 🌍 公开路由(不需要认证) | 
					
						
							|  |  |  |  |         users.POST("/send-code", r.handler.SendCode)      // 发送验证码 | 
					
						
							|  |  |  |  |         users.POST("/register", r.handler.Register)       // 用户注册 | 
					
						
							|  |  |  |  |         users.POST("/login", r.handler.Login)             // 用户登录 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 🔐 需要认证的路由 | 
					
						
							|  |  |  |  |         authenticated := users.Group("") | 
					
						
							|  |  |  |  |         authenticated.Use(r.jwtAuth.Handle()) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             authenticated.GET("/me", r.handler.GetProfile)             // 获取当前用户信息 | 
					
						
							|  |  |  |  |             authenticated.PUT("/me/password", r.handler.ChangePassword) // 修改密码 | 
					
						
							|  |  |  |  |             // 未来扩展示例: | 
					
						
							|  |  |  |  |             // authenticated.PUT("/me", r.handler.UpdateProfile)        // 更新用户信息 | 
					
						
							|  |  |  |  |             // authenticated.DELETE("/me", r.handler.DeleteAccount)     // 删除账户 | 
					
						
							|  |  |  |  |             // authenticated.GET("/me/sessions", r.handler.GetSessions) // 获取登录会话 | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 📱 SMS验证码域路由组(如果需要单独管理SMS) | 
					
						
							|  |  |  |  |     sms := v1.Group("/sms") | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         sms.POST("/send", r.handler.SendCode)  // 发送验证码 | 
					
						
							|  |  |  |  |         // 未来可以添加: | 
					
						
							|  |  |  |  |         // sms.POST("/verify", r.handler.VerifyCode)  // 验证验证码 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. DDD 多域路由架构 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 按域组织路由,支持横向扩展 | 
					
						
							|  |  |  |  | func (r *UserRoutes) RegisterRoutes(router *gin.Engine) { | 
					
						
							|  |  |  |  |     v1 := router.Group("/api/v1") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 👥 用户域 | 
					
						
							|  |  |  |  |     users := v1.Group("/users") | 
					
						
							|  |  |  |  |     // 📦 订单域 | 
					
						
							|  |  |  |  |     orders := v1.Group("/orders") | 
					
						
							|  |  |  |  |     // 🛍️ 商品域 | 
					
						
							|  |  |  |  |     products := v1.Group("/products") | 
					
						
							|  |  |  |  |     // 💰 支付域 | 
					
						
							|  |  |  |  |     payments := v1.Group("/payments") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 多级权限路由分层 | 
					
						
							|  |  |  |  | users := v1.Group("/users") | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     // Level 1: 公开路由 | 
					
						
							|  |  |  |  |     users.POST("/register", r.handler.Register) | 
					
						
							|  |  |  |  |     users.POST("/login", r.handler.Login) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // Level 2: 用户认证路由 | 
					
						
							|  |  |  |  |     authenticated := users.Group("") | 
					
						
							|  |  |  |  |     authenticated.Use(r.jwtAuth.Handle()) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         authenticated.GET("/me", r.handler.GetProfile) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // Level 3: 管理员路由 | 
					
						
							|  |  |  |  |     admin := users.Group("/admin") | 
					
						
							|  |  |  |  |     admin.Use(r.jwtAuth.Handle(), r.adminAuth.Handle()) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         admin.GET("", r.handler.AdminList) | 
					
						
							|  |  |  |  |         admin.DELETE("/:id", r.handler.AdminDelete) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. DDD 路由命名最佳实践 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### ✅ **推荐做法** - 领域导向设计: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 🏢 按业务域划分路由 | 
					
						
							|  |  |  |  | /api/v1/users/*     # 用户域的所有操作 | 
					
						
							|  |  |  |  | /api/v1/orders/*    # 订单域的所有操作 | 
					
						
							|  |  |  |  | /api/v1/products/*  # 商品域的所有操作 | 
					
						
							|  |  |  |  | /api/v1/payments/*  # 支付域的所有操作 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 📋 资源操作使用名词复数 | 
					
						
							|  |  |  |  | POST   /api/v1/users/register      # 用户注册 | 
					
						
							|  |  |  |  | POST   /api/v1/users/login         # 用户登录 | 
					
						
							|  |  |  |  | GET    /api/v1/users/me            # 获取当前用户 | 
					
						
							|  |  |  |  | PUT    /api/v1/users/me/password   # 修改当前用户密码 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 🔗 体现资源关系的嵌套路径 | 
					
						
							|  |  |  |  | GET    /api/v1/users/me/orders     # 获取当前用户的订单 | 
					
						
							|  |  |  |  | GET    /api/v1/orders/123/items    # 获取订单的商品项目 | 
					
						
							|  |  |  |  | POST   /api/v1/products/456/reviews # 为商品添加评论 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### ❌ **避免的做法** - 技术导向设计: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // ❌ 技术导向路径 | 
					
						
							|  |  |  |  | /api/v1/auth/*      # 混合了多个域的认证操作 | 
					
						
							|  |  |  |  | /api/v1/service/*   # 不明确的服务路径 | 
					
						
							|  |  |  |  | /api/v1/api/*       # 冗余的api前缀 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ❌ 动词路径 | 
					
						
							|  |  |  |  | /api/v1/getUserInfo          # 应该用 GET /users/me | 
					
						
							|  |  |  |  | /api/v1/changeUserPassword   # 应该用 PUT /users/me/password | 
					
						
							|  |  |  |  | /api/v1/deleteUserAccount    # 应该用 DELETE /users/me | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ❌ 混合域概念 | 
					
						
							|  |  |  |  | /api/v1/userorders     # 应该分离为 /users/me/orders | 
					
						
							|  |  |  |  | /api/v1/authprofile    # 应该分离为 /users/me | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🔐 权限控制体系 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. JWT 认证中间件 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 强制认证中间件 | 
					
						
							|  |  |  |  | type JWTAuthMiddleware struct { | 
					
						
							|  |  |  |  |     config *config.Config | 
					
						
							|  |  |  |  |     logger *zap.Logger | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 可选认证中间件(支持游客访问) | 
					
						
							|  |  |  |  | type OptionalAuthMiddleware struct { | 
					
						
							|  |  |  |  |     jwtAuth *JWTAuthMiddleware | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 使用方式 | 
					
						
							|  |  |  |  | protected.Use(r.jwtAuth.Handle())      // 强制认证 | 
					
						
							|  |  |  |  | public.Use(r.optionalAuth.Handle())    // 可选认证 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 权限验证模式 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 在Handler中获取当前用户 | 
					
						
							|  |  |  |  | func (h *UserHandler) getCurrentUserID(c *gin.Context) string { | 
					
						
							|  |  |  |  |     userID, exists := c.Get("user_id") | 
					
						
							|  |  |  |  |     if !exists { | 
					
						
							|  |  |  |  |         return "" | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return userID.(string) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 权限检查示例 | 
					
						
							|  |  |  |  | func (h *UserHandler) UpdateProfile(c *gin.Context) { | 
					
						
							|  |  |  |  |     userID := h.getCurrentUserID(c) | 
					
						
							|  |  |  |  |     if userID == "" { | 
					
						
							|  |  |  |  |         h.response.Unauthorized(c, "User not authenticated") | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     // 业务逻辑... | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 权限级别定义 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   **Public**: 公开接口,无需认证 | 
					
						
							|  |  |  |  | -   **User**: 需要用户登录 | 
					
						
							|  |  |  |  | -   **Admin**: 需要管理员权限 | 
					
						
							|  |  |  |  | -   **Owner**: 需要资源所有者权限 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📝 API 响应规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 统一响应格式 (APIResponse 结构) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 标准API响应结构 | 
					
						
							|  |  |  |  | type APIResponse struct { | 
					
						
							|  |  |  |  |     Success    bool                   `json:"success"`              // 操作是否成功 | 
					
						
							|  |  |  |  |     Message    string                 `json:"message"`              // 响应消息(中文) | 
					
						
							|  |  |  |  |     Data       interface{}            `json:"data,omitempty"`       // 响应数据 | 
					
						
							|  |  |  |  |     Errors     interface{}            `json:"errors,omitempty"`     // 错误详情 | 
					
						
							|  |  |  |  |     Pagination *PaginationMeta        `json:"pagination,omitempty"` // 分页信息 | 
					
						
							|  |  |  |  |     Meta       map[string]interface{} `json:"meta,omitempty"`       // 元数据 | 
					
						
							|  |  |  |  |     RequestID  string                 `json:"request_id"`           // 请求追踪ID | 
					
						
							|  |  |  |  |     Timestamp  int64                  `json:"timestamp"`            // Unix时间戳 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 分页元数据结构 | 
					
						
							|  |  |  |  | type PaginationMeta struct { | 
					
						
							|  |  |  |  |     Page       int   `json:"page"`        // 当前页码 | 
					
						
							|  |  |  |  |     PageSize   int   `json:"page_size"`   // 每页大小 | 
					
						
							|  |  |  |  |     Total      int64 `json:"total"`       // 总记录数 | 
					
						
							|  |  |  |  |     TotalPages int   `json:"total_pages"` // 总页数 | 
					
						
							|  |  |  |  |     HasNext    bool  `json:"has_next"`    // 是否有下一页 | 
					
						
							|  |  |  |  |     HasPrev    bool  `json:"has_prev"`    // 是否有上一页 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 成功响应格式示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | // 查询成功响应 (200 OK) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": true, | 
					
						
							|  |  |  |  |     "message": "获取成功", | 
					
						
							|  |  |  |  |     "data": { | 
					
						
							|  |  |  |  |         "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |         "phone": "13800138000", | 
					
						
							|  |  |  |  |         "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |         "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 创建成功响应 (201 Created) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": true, | 
					
						
							|  |  |  |  |     "message": "用户注册成功", | 
					
						
							|  |  |  |  |     "data": { | 
					
						
							|  |  |  |  |         "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |         "phone": "13800138000", | 
					
						
							|  |  |  |  |         "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |         "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 登录成功响应 (200 OK) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": true, | 
					
						
							|  |  |  |  |     "message": "登录成功", | 
					
						
							|  |  |  |  |     "data": { | 
					
						
							|  |  |  |  |         "user": { | 
					
						
							|  |  |  |  |             "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |             "phone": "13800138000", | 
					
						
							|  |  |  |  |             "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |             "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", | 
					
						
							|  |  |  |  |         "token_type": "Bearer", | 
					
						
							|  |  |  |  |         "expires_in": 86400, | 
					
						
							|  |  |  |  |         "login_method": "password" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 分页响应 (200 OK) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": true, | 
					
						
							|  |  |  |  |     "message": "获取成功", | 
					
						
							|  |  |  |  |     "data": [ | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |             "phone": "13800138000", | 
					
						
							|  |  |  |  |             "created_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     ], | 
					
						
							|  |  |  |  |     "pagination": { | 
					
						
							|  |  |  |  |         "page": 1, | 
					
						
							|  |  |  |  |         "page_size": 10, | 
					
						
							|  |  |  |  |         "total": 100, | 
					
						
							|  |  |  |  |         "total_pages": 10, | 
					
						
							|  |  |  |  |         "has_next": true, | 
					
						
							|  |  |  |  |         "has_prev": false | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 错误响应格式示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | // 参数验证错误 (400 Bad Request) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "请求参数错误", | 
					
						
							|  |  |  |  |     "errors": { | 
					
						
							|  |  |  |  |         "phone": ["手机号必须为11位数字"], | 
					
						
							|  |  |  |  |         "password": ["密码长度至少6位"], | 
					
						
							|  |  |  |  |         "confirm_password": ["确认密码必须与密码一致"] | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 验证码错误 (422 Unprocessable Entity) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "验证失败", | 
					
						
							|  |  |  |  |     "errors": { | 
					
						
							|  |  |  |  |         "phone": ["手机号必须为11位数字"], | 
					
						
							|  |  |  |  |         "code": ["验证码必须为6位数字"] | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 业务逻辑错误 (400 Bad Request) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "手机号已存在", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 认证错误 (401 Unauthorized) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "用户未登录或token已过期", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 权限错误 (403 Forbidden) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "权限不足,无法访问此资源", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 资源不存在 (404 Not Found) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "请求的资源不存在", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 资源冲突 (409 Conflict) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "手机号已被注册", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 限流错误 (429 Too Many Requests) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "请求过于频繁,请稍后再试", | 
					
						
							|  |  |  |  |     "meta": { | 
					
						
							|  |  |  |  |         "retry_after": "60s" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 服务器错误 (500 Internal Server Error) | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "服务器内部错误", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 🚦 限流中间件和 TooManyRequests 详解 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 限流配置 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```yaml | 
					
						
							|  |  |  |  | # config.yaml 限流配置 | 
					
						
							|  |  |  |  | ratelimit: | 
					
						
							|  |  |  |  |     requests: 1000 # 每个时间窗口允许的请求数 | 
					
						
							|  |  |  |  |     window: 60s # 时间窗口大小 | 
					
						
							|  |  |  |  |     burst: 200 # 突发请求允许数 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 限流中间件实现 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // RateLimitMiddleware 限流中间件(修复后的版本) | 
					
						
							|  |  |  |  | type RateLimitMiddleware struct { | 
					
						
							|  |  |  |  |     config   *config.Config | 
					
						
							|  |  |  |  |     response interfaces.ResponseBuilder  // ✅ 使用统一响应格式 | 
					
						
							|  |  |  |  |     limiters map[string]*rate.Limiter | 
					
						
							|  |  |  |  |     mutex    sync.RWMutex | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Handle 限流处理逻辑 | 
					
						
							|  |  |  |  | func (m *RateLimitMiddleware) Handle() gin.HandlerFunc { | 
					
						
							|  |  |  |  |     return func(c *gin.Context) { | 
					
						
							|  |  |  |  |         clientID := m.getClientID(c)  // 获取客户端ID(通常是IP地址) | 
					
						
							|  |  |  |  |         limiter := m.getLimiter(clientID) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if !limiter.Allow() { | 
					
						
							|  |  |  |  |             // 添加限流头部信息 | 
					
						
							|  |  |  |  |             c.Header("X-RateLimit-Limit", fmt.Sprintf("%d", m.config.RateLimit.Requests)) | 
					
						
							|  |  |  |  |             c.Header("X-RateLimit-Window", m.config.RateLimit.Window.String()) | 
					
						
							|  |  |  |  |             c.Header("Retry-After", "60") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // ✅ 使用统一的TooManyRequests响应格式(修复前是c.JSON) | 
					
						
							|  |  |  |  |             m.response.TooManyRequests(c, "请求过于频繁,请稍后再试") | 
					
						
							|  |  |  |  |             c.Abort() | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         c.Next() | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 多层限流保护 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 🔹 1. 全局IP限流(中间件层) | 
					
						
							|  |  |  |  | // 通过RateLimitMiddleware自动处理,返回429状态码 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 🔹 2. 短信发送限流(业务层) | 
					
						
							|  |  |  |  | func (s *SMSCodeService) checkRateLimit(ctx context.Context, phone string) error { | 
					
						
							|  |  |  |  |     // 最小发送间隔检查 | 
					
						
							|  |  |  |  |     lastSentKey := fmt.Sprintf("sms:last_sent:%s", phone) | 
					
						
							|  |  |  |  |     if lastSent exists && now.Sub(lastSent) < s.config.RateLimit.MinInterval { | 
					
						
							|  |  |  |  |         return fmt.Errorf("请等待 %v 后再试", s.config.RateLimit.MinInterval) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 每小时发送限制 | 
					
						
							|  |  |  |  |     hourlyKey := fmt.Sprintf("sms:hourly:%s:%s", phone, now.Format("2006010215")) | 
					
						
							|  |  |  |  |     if hourlyCount >= s.config.RateLimit.HourlyLimit { | 
					
						
							|  |  |  |  |         return fmt.Errorf("每小时最多发送 %d 条短信", s.config.RateLimit.HourlyLimit) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 🔹 3. Handler层限流错误处理 | 
					
						
							|  |  |  |  | func (h *UserHandler) SendSMSCode(c *gin.Context) { | 
					
						
							|  |  |  |  |     err := h.smsCodeService.SendCode(ctx, &req) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         // 检查是否是限流错误 | 
					
						
							|  |  |  |  |         if strings.Contains(err.Error(), "请等待") || | 
					
						
							|  |  |  |  |            strings.Contains(err.Error(), "最多发送") { | 
					
						
							|  |  |  |  |             // ✅ 使用TooManyRequests响应 | 
					
						
							|  |  |  |  |             h.response.TooManyRequests(c, err.Error()) | 
					
						
							|  |  |  |  |             return | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         h.response.BadRequest(c, err.Error()) | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     h.response.Success(c, nil, "验证码发送成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 限流响应示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **中间件层限流**(全局 IP 限流): | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "请求过于频繁,请稍后再试", | 
					
						
							|  |  |  |  |     "meta": { | 
					
						
							|  |  |  |  |         "retry_after": "60s" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **业务层限流**(短信发送限流): | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "请等待 60 秒后再试", | 
					
						
							|  |  |  |  |     "meta": { | 
					
						
							|  |  |  |  |         "retry_after": "60s" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### TooManyRequests 使用场景 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   🚫 **全局限流**: IP 请求频率限制 | 
					
						
							|  |  |  |  | -   📱 **短信限流**: 验证码发送频率限制 | 
					
						
							|  |  |  |  | -   🔐 **登录限流**: 防止暴力破解 | 
					
						
							|  |  |  |  | -   📧 **邮件限流**: 邮件发送频率限制 | 
					
						
							|  |  |  |  | -   <20><> **搜索限流**: 防止恶意搜索 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. ResponseBuilder 响应构建器使用 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 成功响应 | 
					
						
							|  |  |  |  | h.response.Success(c, data, "获取成功") | 
					
						
							|  |  |  |  | h.response.Created(c, data, "创建成功") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 客户端错误响应 | 
					
						
							|  |  |  |  | h.response.BadRequest(c, "请求参数错误", validationErrors) | 
					
						
							|  |  |  |  | h.response.Unauthorized(c, "用户未登录或token已过期") | 
					
						
							|  |  |  |  | h.response.Forbidden(c, "权限不足,无法访问此资源") | 
					
						
							|  |  |  |  | h.response.NotFound(c, "请求的资源不存在") | 
					
						
							|  |  |  |  | h.response.Conflict(c, "手机号已被注册") | 
					
						
							|  |  |  |  | h.response.ValidationError(c, validationErrors) | 
					
						
							|  |  |  |  | h.response.TooManyRequests(c, "请求过于频繁,请稍后再试") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 服务器错误响应 | 
					
						
							|  |  |  |  | h.response.InternalError(c, "服务器内部错误") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 分页响应 | 
					
						
							|  |  |  |  | h.response.Paginated(c, data, pagination) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 自定义响应 | 
					
						
							|  |  |  |  | h.response.CustomResponse(c, statusCode, data) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 5. 错误处理分层架构 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 1. Handler层 - HTTP错误处理 | 
					
						
							|  |  |  |  | func (h *UserHandler) Register(c *gin.Context) { | 
					
						
							|  |  |  |  |     var req dto.RegisterRequest | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证请求参数 | 
					
						
							|  |  |  |  |     if err := h.validator.BindAndValidate(c, &req); err != nil { | 
					
						
							|  |  |  |  |         return // 验证器已处理响应,直接返回 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 调用业务服务 | 
					
						
							|  |  |  |  |     user, err := h.userService.Register(c.Request.Context(), &req) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         h.logger.Error("用户注册失败", zap.Error(err)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 根据错误类型返回相应响应 | 
					
						
							|  |  |  |  |         switch { | 
					
						
							|  |  |  |  |         case strings.Contains(err.Error(), "手机号已存在"): | 
					
						
							|  |  |  |  |             h.response.Conflict(c, "手机号已被注册") | 
					
						
							|  |  |  |  |         case strings.Contains(err.Error(), "验证码错误"): | 
					
						
							|  |  |  |  |             h.response.BadRequest(c, "验证码错误或已过期") | 
					
						
							|  |  |  |  |         default: | 
					
						
							|  |  |  |  |             h.response.InternalError(c, "注册失败,请稍后重试") | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 成功响应 | 
					
						
							|  |  |  |  |     response := dto.FromEntity(user) | 
					
						
							|  |  |  |  |     h.response.Created(c, response, "用户注册成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 2. 验证器层 - 参数验证错误 | 
					
						
							|  |  |  |  | func (v *RequestValidator) BindAndValidate(c *gin.Context, dto interface{}) error { | 
					
						
							|  |  |  |  |     // 绑定请求体 | 
					
						
							|  |  |  |  |     if err := c.ShouldBindJSON(dto); err != nil { | 
					
						
							|  |  |  |  |         v.response.BadRequest(c, "请求体格式错误", err.Error()) | 
					
						
							|  |  |  |  |         return err | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证数据 | 
					
						
							|  |  |  |  |     if err := v.validator.Struct(dto); err != nil { | 
					
						
							|  |  |  |  |         validationErrors := v.formatValidationErrors(err) | 
					
						
							|  |  |  |  |         v.response.ValidationError(c, validationErrors) | 
					
						
							|  |  |  |  |         return err | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 3. 业务服务层 - 业务逻辑错误 | 
					
						
							|  |  |  |  | func (s *UserService) Register(ctx context.Context, req *dto.RegisterRequest) (*entities.User, error) { | 
					
						
							|  |  |  |  |     // 验证手机号格式 | 
					
						
							|  |  |  |  |     if !s.isValidPhone(req.Phone) { | 
					
						
							|  |  |  |  |         return nil, fmt.Errorf("手机号格式不正确") | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 检查手机号是否已存在 | 
					
						
							|  |  |  |  |     if err := s.checkPhoneDuplicate(ctx, req.Phone); err != nil { | 
					
						
							|  |  |  |  |         return nil, fmt.Errorf("手机号已存在") | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证验证码 | 
					
						
							|  |  |  |  |     if err := s.smsCodeService.VerifyCode(ctx, req.Phone, req.Code, entities.SMSSceneRegister); err != nil { | 
					
						
							|  |  |  |  |         return nil, fmt.Errorf("验证码错误或已过期") | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 创建用户... | 
					
						
							|  |  |  |  |     return user, nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🔄 RESTful API 设计规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. DDD 架构下的 URL 设计规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 🏢 领域驱动的资源设计 | 
					
						
							|  |  |  |  | GET    /api/v1/users/me           # 获取当前用户信息 | 
					
						
							|  |  |  |  | PUT    /api/v1/users/me           # 更新当前用户信息 | 
					
						
							|  |  |  |  | DELETE /api/v1/users/me           # 删除当前用户账户 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 🔐 认证相关操作(仍在用户域内) | 
					
						
							|  |  |  |  | POST   /api/v1/users/register     # 用户注册 | 
					
						
							|  |  |  |  | POST   /api/v1/users/login        # 用户登录 | 
					
						
							|  |  |  |  | POST   /api/v1/users/logout       # 用户登出 | 
					
						
							|  |  |  |  | POST   /api/v1/users/send-code    # 发送验证码 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 📱 SMS验证码域操作 | 
					
						
							|  |  |  |  | POST   /api/v1/sms/send           # 发送验证码 | 
					
						
							|  |  |  |  | POST   /api/v1/sms/verify         # 验证验证码 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 🔗 子资源嵌套(当前用户的资源) | 
					
						
							|  |  |  |  | GET    /api/v1/users/me/orders    # 获取当前用户的订单 | 
					
						
							|  |  |  |  | GET    /api/v1/users/me/favorites # 获取当前用户的收藏 | 
					
						
							|  |  |  |  | POST   /api/v1/users/me/favorites # 添加收藏 | 
					
						
							|  |  |  |  | DELETE /api/v1/users/me/favorites/:id # 删除收藏 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 🛍️ 跨域资源关系 | 
					
						
							|  |  |  |  | GET    /api/v1/orders/123         # 获取订单详情 | 
					
						
							|  |  |  |  | GET    /api/v1/orders/123/items   # 获取订单商品 | 
					
						
							|  |  |  |  | POST   /api/v1/products/456/reviews # 为商品添加评论 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 🎯 特殊操作使用动词(在对应域内) | 
					
						
							|  |  |  |  | PUT    /api/v1/users/me/password  # 修改密码 | 
					
						
							|  |  |  |  | POST   /api/v1/orders/123/cancel  # 取消订单 | 
					
						
							|  |  |  |  | POST   /api/v1/payments/123/refund # 退款操作 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. DDD 多域 API 路径设计示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 👥 用户域 (User Domain) | 
					
						
							|  |  |  |  | POST   /api/v1/users/register          # 用户注册 | 
					
						
							|  |  |  |  | POST   /api/v1/users/login             # 用户登录 | 
					
						
							|  |  |  |  | GET    /api/v1/users/me               # 获取当前用户 | 
					
						
							|  |  |  |  | PUT    /api/v1/users/me               # 更新用户信息 | 
					
						
							|  |  |  |  | PUT    /api/v1/users/me/password      # 修改密码 | 
					
						
							|  |  |  |  | GET    /api/v1/users/me/sessions      # 获取登录会话 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 📦 订单域 (Order Domain) | 
					
						
							|  |  |  |  | GET    /api/v1/orders                 # 获取订单列表 | 
					
						
							|  |  |  |  | POST   /api/v1/orders                 # 创建订单 | 
					
						
							|  |  |  |  | GET    /api/v1/orders/:id             # 获取订单详情 | 
					
						
							|  |  |  |  | PUT    /api/v1/orders/:id             # 更新订单 | 
					
						
							|  |  |  |  | POST   /api/v1/orders/:id/cancel      # 取消订单 | 
					
						
							|  |  |  |  | GET    /api/v1/orders/:id/items       # 获取订单商品 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 🛍️ 商品域 (Product Domain) | 
					
						
							|  |  |  |  | GET    /api/v1/products               # 获取商品列表 | 
					
						
							|  |  |  |  | POST   /api/v1/products               # 创建商品 | 
					
						
							|  |  |  |  | GET    /api/v1/products/:id           # 获取商品详情 | 
					
						
							|  |  |  |  | PUT    /api/v1/products/:id           # 更新商品 | 
					
						
							|  |  |  |  | GET    /api/v1/products/:id/reviews   # 获取商品评论 | 
					
						
							|  |  |  |  | POST   /api/v1/products/:id/reviews   # 添加商品评论 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 💰 支付域 (Payment Domain) | 
					
						
							|  |  |  |  | POST   /api/v1/payments               # 创建支付 | 
					
						
							|  |  |  |  | GET    /api/v1/payments/:id           # 获取支付状态 | 
					
						
							|  |  |  |  | POST   /api/v1/payments/:id/refund    # 申请退款 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 📱 通知域 (Notification Domain) | 
					
						
							|  |  |  |  | GET    /api/v1/notifications          # 获取通知列表 | 
					
						
							|  |  |  |  | PUT    /api/v1/notifications/:id/read # 标记通知为已读 | 
					
						
							|  |  |  |  | POST   /api/v1/sms/send              # 发送短信验证码 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. HTTP 状态码规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # ✅ 成功响应 (2xx) | 
					
						
							|  |  |  |  | 200 OK                    # 查询成功 (GET /api/v1/users/me) | 
					
						
							|  |  |  |  | 201 Created               # 创建成功 (POST /api/v1/users/register) | 
					
						
							|  |  |  |  | 204 No Content            # 删除成功 (DELETE /api/v1/users/me) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # ❌ 客户端错误 (4xx) | 
					
						
							|  |  |  |  | 400 Bad Request           # 请求参数错误 | 
					
						
							|  |  |  |  | 401 Unauthorized          # 未认证 (需要登录) | 
					
						
							|  |  |  |  | 403 Forbidden             # 无权限 (登录但权限不足) | 
					
						
							|  |  |  |  | 404 Not Found             # 资源不存在 | 
					
						
							|  |  |  |  | 422 Unprocessable Entity  # 业务验证失败 | 
					
						
							|  |  |  |  | 429 Too Many Requests     # 请求频率限制 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # ⚠️ 服务器错误 (5xx) | 
					
						
							|  |  |  |  | 500 Internal Server Error # 服务器内部错误 | 
					
						
							|  |  |  |  | 502 Bad Gateway           # 网关错误 | 
					
						
							|  |  |  |  | 503 Service Unavailable   # 服务不可用 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. 状态码在 DDD 架构中的应用 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 用户域状态码示例 | 
					
						
							|  |  |  |  | func (h *UserHandler) Login(c *gin.Context) { | 
					
						
							|  |  |  |  |     // 参数验证失败 | 
					
						
							|  |  |  |  |     if err := h.validator.BindAndValidate(c, &req); err != nil { | 
					
						
							|  |  |  |  |         // 422 Unprocessable Entity | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     user, err := h.userService.Login(ctx, &req) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         switch { | 
					
						
							|  |  |  |  |         case errors.Is(err, domain.ErrUserNotFound): | 
					
						
							|  |  |  |  |             h.response.NotFound(c, "用户不存在")  // 404 | 
					
						
							|  |  |  |  |         case errors.Is(err, domain.ErrInvalidPassword): | 
					
						
							|  |  |  |  |             h.response.Unauthorized(c, "密码错误") // 401 | 
					
						
							|  |  |  |  |         case errors.Is(err, domain.ErrUserBlocked): | 
					
						
							|  |  |  |  |             h.response.Forbidden(c, "账户已被禁用") // 403 | 
					
						
							|  |  |  |  |         default: | 
					
						
							|  |  |  |  |             h.response.InternalError(c, "登录失败") // 500 | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     h.response.Success(c, user, "登录成功") // 200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (h *UserHandler) Register(c *gin.Context) { | 
					
						
							|  |  |  |  |     user, err := h.userService.Register(ctx, &req) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         switch { | 
					
						
							|  |  |  |  |         case errors.Is(err, domain.ErrPhoneExists): | 
					
						
							|  |  |  |  |             h.response.Conflict(c, "手机号已存在")     // 409 | 
					
						
							|  |  |  |  |         case errors.Is(err, domain.ErrInvalidCode): | 
					
						
							|  |  |  |  |             h.response.BadRequest(c, "验证码错误")    // 400 | 
					
						
							|  |  |  |  |         default: | 
					
						
							|  |  |  |  |             h.response.InternalError(c, "注册失败")   // 500 | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     h.response.Created(c, user, "注册成功") // 201 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## ✅ 数据验证规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 结构体标签验证 (中文提示) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 用户注册请求验证 | 
					
						
							|  |  |  |  | type RegisterRequest struct { | 
					
						
							|  |  |  |  |     Phone           string `json:"phone" binding:"required,len=11" example:"13800138000"` | 
					
						
							|  |  |  |  |     Password        string `json:"password" binding:"required,min=6,max=128" example:"password123"` | 
					
						
							|  |  |  |  |     ConfirmPassword string `json:"confirm_password" binding:"required,eqfield=Password" example:"password123"` | 
					
						
							|  |  |  |  |     Code            string `json:"code" binding:"required,len=6" example:"123456"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 用户登录请求验证 | 
					
						
							|  |  |  |  | type LoginWithPasswordRequest struct { | 
					
						
							|  |  |  |  |     Phone    string `json:"phone" binding:"required,len=11" example:"13800138000"` | 
					
						
							|  |  |  |  |     Password string `json:"password" binding:"required" example:"password123"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 修改密码请求验证 | 
					
						
							|  |  |  |  | type ChangePasswordRequest struct { | 
					
						
							|  |  |  |  |     OldPassword        string `json:"old_password" binding:"required" example:"oldpassword123"` | 
					
						
							|  |  |  |  |     NewPassword        string `json:"new_password" binding:"required,min=6,max=128" example:"newpassword123"` | 
					
						
							|  |  |  |  |     ConfirmNewPassword string `json:"confirm_new_password" binding:"required,eqfield=NewPassword" example:"newpassword123"` | 
					
						
							|  |  |  |  |     Code               string `json:"code" binding:"required,len=6" example:"123456"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 官方中文翻译包集成 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 项目集成了 `github.com/go-playground/validator/v10/translations/zh` 官方中文翻译包,自动提供专业的中文验证错误消息。 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **集成优势:** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   ✅ **官方支持**: 使用 validator 官方维护的中文翻译 | 
					
						
							|  |  |  |  | -   ✅ **专业翻译**: 所有标准验证规则都有准确的中文翻译 | 
					
						
							|  |  |  |  | -   ✅ **自动更新**: 跟随 validator 版本自动获得新功能的中文支持 | 
					
						
							|  |  |  |  | -   ✅ **智能结合**: 官方翻译 + 自定义字段名映射,提供最佳用户体验 | 
					
						
							|  |  |  |  | -   ✅ **兼容性好**: 保持与现有 API 接口的完全兼容 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 创建支持中文翻译的验证器 | 
					
						
							|  |  |  |  | func NewRequestValidatorZh(response interfaces.ResponseBuilder) interfaces.RequestValidator { | 
					
						
							|  |  |  |  |     // 创建验证器实例 | 
					
						
							|  |  |  |  |     validate := validator.New() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 创建中文locale | 
					
						
							|  |  |  |  |     zhLocale := zh.New() | 
					
						
							|  |  |  |  |     uni := ut.New(zhLocale, zhLocale) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 获取中文翻译器 | 
					
						
							|  |  |  |  |     trans, _ := uni.GetTranslator("zh") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 注册官方中文翻译 | 
					
						
							|  |  |  |  |     zh_translations.RegisterDefaultTranslations(validate, trans) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 注册自定义验证器和翻译 | 
					
						
							|  |  |  |  |     registerCustomValidatorsZh(validate, trans) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return &RequestValidatorZh{ | 
					
						
							|  |  |  |  |         validator:  validate, | 
					
						
							|  |  |  |  |         translator: trans, | 
					
						
							|  |  |  |  |         response:   response, | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 手机号验证器 | 
					
						
							|  |  |  |  | func validatePhone(fl validator.FieldLevel) bool { | 
					
						
							|  |  |  |  |     phone := fl.Field().String() | 
					
						
							|  |  |  |  |     if phone == "" { | 
					
						
							|  |  |  |  |         return true // 空值由required标签处理 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 中国手机号验证:11位,以1开头 | 
					
						
							|  |  |  |  |     matched, _ := regexp.MatchString(`^1[3-9]\d{9}$`, phone) | 
					
						
							|  |  |  |  |     return matched | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 用户名验证器 | 
					
						
							|  |  |  |  | func validateUsername(fl validator.FieldLevel) bool { | 
					
						
							|  |  |  |  |     username := fl.Field().String() | 
					
						
							|  |  |  |  |     if username == "" { | 
					
						
							|  |  |  |  |         return true // 空值由required标签处理 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 用户名规则:3-30字符,字母数字下划线,不能数字开头 | 
					
						
							|  |  |  |  |     if len(username) < 3 || len(username) > 30 { | 
					
						
							|  |  |  |  |         return false | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     matched, _ := regexp.MatchString(`^[a-zA-Z][a-zA-Z0-9_]*$`, username) | 
					
						
							|  |  |  |  |     return matched | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 强密码验证器 | 
					
						
							|  |  |  |  | func validateStrongPassword(fl validator.FieldLevel) bool { | 
					
						
							|  |  |  |  |     password := fl.Field().String() | 
					
						
							|  |  |  |  |     if password == "" { | 
					
						
							|  |  |  |  |         return true // 空值由required标签处理 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 密码强度:至少8位,包含大小写字母和数字 | 
					
						
							|  |  |  |  |     if len(password) < 8 { | 
					
						
							|  |  |  |  |         return false | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     hasUpper := regexp.MustCompile(`[A-Z]`).MatchString(password) | 
					
						
							|  |  |  |  |     hasLower := regexp.MustCompile(`[a-z]`).MatchString(password) | 
					
						
							|  |  |  |  |     hasDigit := regexp.MustCompile(`\d`).MatchString(password) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return hasUpper && hasLower && hasDigit | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 自定义验证器和翻译注册 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 注册自定义验证器和中文翻译 | 
					
						
							|  |  |  |  | func registerCustomValidatorsZh(v *validator.Validate, trans ut.Translator) { | 
					
						
							|  |  |  |  |     // 注册手机号验证器 | 
					
						
							|  |  |  |  |     v.RegisterValidation("phone", validatePhoneZh) | 
					
						
							|  |  |  |  |     v.RegisterTranslation("phone", trans, func(ut ut.Translator) error { | 
					
						
							|  |  |  |  |         return ut.Add("phone", "{0}必须是有效的手机号", true) | 
					
						
							|  |  |  |  |     }, func(ut ut.Translator, fe validator.FieldError) string { | 
					
						
							|  |  |  |  |         t, _ := ut.T("phone", fe.Field()) | 
					
						
							|  |  |  |  |         return t | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 注册用户名验证器 | 
					
						
							|  |  |  |  |     v.RegisterValidation("username", validateUsernameZh) | 
					
						
							|  |  |  |  |     v.RegisterTranslation("username", trans, func(ut ut.Translator) error { | 
					
						
							|  |  |  |  |         return ut.Add("username", "{0}格式不正确,只能包含字母、数字、下划线,且不能以数字开头", true) | 
					
						
							|  |  |  |  |     }, func(ut ut.Translator, fe validator.FieldError) string { | 
					
						
							|  |  |  |  |         t, _ := ut.T("username", fe.Field()) | 
					
						
							|  |  |  |  |         return t | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 注册密码强度验证器 | 
					
						
							|  |  |  |  |     v.RegisterValidation("strong_password", validateStrongPasswordZh) | 
					
						
							|  |  |  |  |     v.RegisterTranslation("strong_password", trans, func(ut ut.Translator) error { | 
					
						
							|  |  |  |  |         return ut.Add("strong_password", "{0}强度不足,必须包含大小写字母和数字,且不少于8位", true) | 
					
						
							|  |  |  |  |     }, func(ut ut.Translator, fe validator.FieldError) string { | 
					
						
							|  |  |  |  |         t, _ := ut.T("strong_password", fe.Field()) | 
					
						
							|  |  |  |  |         return t | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 智能错误格式化(官方翻译 + 自定义字段名) | 
					
						
							|  |  |  |  | func (v *RequestValidatorZh) formatValidationErrorsZh(err error) map[string][]string { | 
					
						
							|  |  |  |  |     errors := make(map[string][]string) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if validationErrors, ok := err.(validator.ValidationErrors); ok { | 
					
						
							|  |  |  |  |         for _, fieldError := range validationErrors { | 
					
						
							|  |  |  |  |             fieldName := v.getFieldNameZh(fieldError) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 使用官方翻译器获取中文错误消息 | 
					
						
							|  |  |  |  |             errorMessage := fieldError.Translate(v.translator) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             // 替换字段名为中文显示名称 | 
					
						
							|  |  |  |  |             fieldDisplayName := v.getFieldDisplayName(fieldError.Field()) | 
					
						
							|  |  |  |  |             if fieldDisplayName != fieldError.Field() { | 
					
						
							|  |  |  |  |                 errorMessage = strings.ReplaceAll(errorMessage, fieldError.Field(), fieldDisplayName) | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if _, exists := errors[fieldName]; !exists { | 
					
						
							|  |  |  |  |                 errors[fieldName] = []string{} | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             errors[fieldName] = append(errors[fieldName], errorMessage) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return errors | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. 中文翻译效果对比 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **标准验证规则** (官方翻译) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "验证失败", | 
					
						
							|  |  |  |  |     "errors": { | 
					
						
							|  |  |  |  |         "phone": ["手机号必须是有效的手机号"], | 
					
						
							|  |  |  |  |         "email": ["email必须是一个有效的邮箱"], | 
					
						
							|  |  |  |  |         "password": ["password长度必须至少为8个字符"], | 
					
						
							|  |  |  |  |         "confirm_password": ["ConfirmPassword必须等于Password"], | 
					
						
							|  |  |  |  |         "age": ["age必须大于或等于18"] | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **自定义验证规则** (自定义翻译) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "验证失败", | 
					
						
							|  |  |  |  |     "errors": { | 
					
						
							|  |  |  |  |         "username": [ | 
					
						
							|  |  |  |  |             "用户名格式不正确,只能包含字母、数字、下划线,且不能以数字开头" | 
					
						
							|  |  |  |  |         ], | 
					
						
							|  |  |  |  |         "password": ["密码强度不足,必须包含大小写字母和数字,且不少于8位"] | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **优化后的用户体验** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 通过字段名映射,最终用户看到的是: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "验证失败", | 
					
						
							|  |  |  |  |     "errors": { | 
					
						
							|  |  |  |  |         "phone": ["手机号必须是有效的手机号"], | 
					
						
							|  |  |  |  |         "email": ["邮箱必须是一个有效的邮箱"], | 
					
						
							|  |  |  |  |         "password": ["密码长度必须至少为8个字符"], | 
					
						
							|  |  |  |  |         "confirm_password": ["确认密码必须等于密码"], | 
					
						
							|  |  |  |  |         "age": ["年龄必须大于或等于18"] | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. 验证器使用示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | func (h *UserHandler) Register(c *gin.Context) { | 
					
						
							|  |  |  |  |     var req dto.RegisterRequest | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证器会自动处理错误响应,返回中文错误信息 | 
					
						
							|  |  |  |  |     if err := h.validator.BindAndValidate(c, &req); err != nil { | 
					
						
							|  |  |  |  |         return // 验证失败,已返回带中文提示的错误响应 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 继续业务逻辑... | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 验证失败时的响应示例 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "验证失败", | 
					
						
							|  |  |  |  |     "errors": { | 
					
						
							|  |  |  |  |         "phone": ["手机号 长度必须为 11 位"], | 
					
						
							|  |  |  |  |         "password": ["密码 长度不能少于 6 位"], | 
					
						
							|  |  |  |  |         "confirm_password": ["确认密码 必须与 密码 一致"], | 
					
						
							|  |  |  |  |         "code": ["验证码 长度必须为 6 位"] | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📊 分页和查询规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 分页参数 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | type UserListRequest struct { | 
					
						
							|  |  |  |  |     Page     int                    `form:"page" binding:"min=1"` | 
					
						
							|  |  |  |  |     PageSize int                    `form:"page_size" binding:"min=1,max=100"` | 
					
						
							|  |  |  |  |     Sort     string                 `form:"sort"`      // 排序字段 | 
					
						
							|  |  |  |  |     Order    string                 `form:"order"`     // asc/desc | 
					
						
							|  |  |  |  |     Search   string                 `form:"search"`    // 搜索关键词 | 
					
						
							|  |  |  |  |     Filters  map[string]interface{} `form:"filters"`   // 过滤条件 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 查询接口设计 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | GET /api/v1/users?page=1&page_size=20&sort=created_at&order=desc&search=john | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🔧 中间件使用规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 全局中间件(按优先级) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/container/container.go - RegisterMiddlewares | 
					
						
							|  |  |  |  | router.RegisterMiddleware(requestID)        // 95 - 请求ID | 
					
						
							|  |  |  |  | router.RegisterMiddleware(security)         // 85 - 安全头部 | 
					
						
							|  |  |  |  | router.RegisterMiddleware(responseTime)     // 75 - 响应时间 | 
					
						
							|  |  |  |  | router.RegisterMiddleware(cors)             // 70 - CORS | 
					
						
							|  |  |  |  | router.RegisterMiddleware(rateLimit)        // 65 - 限流 | 
					
						
							|  |  |  |  | router.RegisterMiddleware(requestLogger)    // 80 - 请求日志 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 路由级中间件 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 认证中间件 | 
					
						
							|  |  |  |  | protected.Use(r.jwtAuth.Handle()) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 可选认证中间件 | 
					
						
							|  |  |  |  | public.Use(r.optionalAuth.Handle()) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 自定义中间件 | 
					
						
							|  |  |  |  | adminRoutes.Use(r.adminAuth.Handle()) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🎯 错误处理规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 业务错误分类 (中文错误码和消息) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 业务错误结构 | 
					
						
							|  |  |  |  | type BusinessError struct { | 
					
						
							|  |  |  |  |     Code    string      `json:"code"`    // 错误码 | 
					
						
							|  |  |  |  |     Message string      `json:"message"` // 中文错误消息 | 
					
						
							|  |  |  |  |     Details interface{} `json:"details,omitempty"` // 错误详情 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 用户域错误码定义 | 
					
						
							|  |  |  |  | const ( | 
					
						
							|  |  |  |  |     // 用户相关错误 | 
					
						
							|  |  |  |  |     ErrUserNotFound        = "USER_NOT_FOUND"        // 用户不存在 | 
					
						
							|  |  |  |  |     ErrUserExists          = "USER_EXISTS"           // 用户已存在 | 
					
						
							|  |  |  |  |     ErrPhoneExists         = "PHONE_EXISTS"          // 手机号已存在 | 
					
						
							|  |  |  |  |     ErrInvalidCredentials  = "INVALID_CREDENTIALS"   // 登录凭据无效 | 
					
						
							|  |  |  |  |     ErrInvalidPassword     = "INVALID_PASSWORD"      // 密码错误 | 
					
						
							|  |  |  |  |     ErrUserBlocked         = "USER_BLOCKED"          // 用户被禁用 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证码相关错误 | 
					
						
							|  |  |  |  |     ErrInvalidCode         = "INVALID_CODE"          // 验证码错误 | 
					
						
							|  |  |  |  |     ErrCodeExpired         = "CODE_EXPIRED"          // 验证码已过期 | 
					
						
							|  |  |  |  |     ErrCodeUsed            = "CODE_USED"             // 验证码已使用 | 
					
						
							|  |  |  |  |     ErrCodeSendTooFrequent = "CODE_SEND_TOO_FREQUENT" // 验证码发送过于频繁 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 请求相关错误 | 
					
						
							|  |  |  |  |     ErrValidationFailed    = "VALIDATION_FAILED"     // 参数验证失败 | 
					
						
							|  |  |  |  |     ErrInvalidRequest      = "INVALID_REQUEST"       // 请求格式错误 | 
					
						
							|  |  |  |  |     ErrMissingParam        = "MISSING_PARAM"         // 缺少必需参数 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 权限相关错误 | 
					
						
							|  |  |  |  |     ErrUnauthorized        = "UNAUTHORIZED"          // 未认证 | 
					
						
							|  |  |  |  |     ErrForbidden           = "FORBIDDEN"             // 权限不足 | 
					
						
							|  |  |  |  |     ErrTokenExpired        = "TOKEN_EXPIRED"         // Token已过期 | 
					
						
							|  |  |  |  |     ErrTokenInvalid        = "TOKEN_INVALID"         // Token无效 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 系统相关错误 | 
					
						
							|  |  |  |  |     ErrInternalServer      = "INTERNAL_SERVER_ERROR" // 服务器内部错误 | 
					
						
							|  |  |  |  |     ErrServiceUnavailable  = "SERVICE_UNAVAILABLE"   // 服务不可用 | 
					
						
							|  |  |  |  |     ErrRateLimitExceeded   = "RATE_LIMIT_EXCEEDED"   // 请求频率超限 | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 错误消息映射(中文) | 
					
						
							|  |  |  |  | var ErrorMessages = map[string]string{ | 
					
						
							|  |  |  |  |     // 用户相关 | 
					
						
							|  |  |  |  |     ErrUserNotFound:        "用户不存在", | 
					
						
							|  |  |  |  |     ErrUserExists:          "用户已存在", | 
					
						
							|  |  |  |  |     ErrPhoneExists:         "手机号已被注册", | 
					
						
							|  |  |  |  |     ErrInvalidCredentials:  "用户名或密码错误", | 
					
						
							|  |  |  |  |     ErrInvalidPassword:     "密码错误", | 
					
						
							|  |  |  |  |     ErrUserBlocked:         "账户已被禁用,请联系客服", | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证码相关 | 
					
						
							|  |  |  |  |     ErrInvalidCode:         "验证码错误", | 
					
						
							|  |  |  |  |     ErrCodeExpired:         "验证码已过期,请重新获取", | 
					
						
							|  |  |  |  |     ErrCodeUsed:            "验证码已使用,请重新获取", | 
					
						
							|  |  |  |  |     ErrCodeSendTooFrequent: "验证码发送过于频繁,请稍后再试", | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 请求相关 | 
					
						
							|  |  |  |  |     ErrValidationFailed:    "请求参数验证失败", | 
					
						
							|  |  |  |  |     ErrInvalidRequest:      "请求格式错误", | 
					
						
							|  |  |  |  |     ErrMissingParam:        "缺少必需参数", | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 权限相关 | 
					
						
							|  |  |  |  |     ErrUnauthorized:        "用户未登录或登录已过期", | 
					
						
							|  |  |  |  |     ErrForbidden:           "权限不足,无法访问此资源", | 
					
						
							|  |  |  |  |     ErrTokenExpired:        "登录已过期,请重新登录", | 
					
						
							|  |  |  |  |     ErrTokenInvalid:        "登录信息无效,请重新登录", | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 系统相关 | 
					
						
							|  |  |  |  |     ErrInternalServer:      "服务器内部错误,请稍后重试", | 
					
						
							|  |  |  |  |     ErrServiceUnavailable:  "服务暂时不可用,请稍后重试", | 
					
						
							|  |  |  |  |     ErrRateLimitExceeded:   "请求过于频繁,请稍后再试", | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 创建业务错误 | 
					
						
							|  |  |  |  | func NewBusinessError(code string, details ...interface{}) *BusinessError { | 
					
						
							|  |  |  |  |     message := ErrorMessages[code] | 
					
						
							|  |  |  |  |     if message == "" { | 
					
						
							|  |  |  |  |         message = "未知错误" | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     err := &BusinessError{ | 
					
						
							|  |  |  |  |         Code:    code, | 
					
						
							|  |  |  |  |         Message: message, | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if len(details) > 0 { | 
					
						
							|  |  |  |  |         err.Details = details[0] | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     return err | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 实现error接口 | 
					
						
							|  |  |  |  | func (e *BusinessError) Error() string { | 
					
						
							|  |  |  |  |     return e.Message | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 错误处理模式示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 服务层错误处理 | 
					
						
							|  |  |  |  | func (s *UserService) GetByID(ctx context.Context, id string) (*entities.User, error) { | 
					
						
							|  |  |  |  |     user, err := s.repo.GetByID(ctx, id) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         if errors.Is(err, gorm.ErrRecordNotFound) { | 
					
						
							|  |  |  |  |             return nil, NewBusinessError(ErrUserNotFound) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         s.logger.Error("获取用户失败", zap.Error(err), zap.String("user_id", id)) | 
					
						
							|  |  |  |  |         return nil, NewBusinessError(ErrInternalServer) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return user, nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | func (s *UserService) Register(ctx context.Context, req *dto.RegisterRequest) (*entities.User, error) { | 
					
						
							|  |  |  |  |     // 检查手机号是否已存在 | 
					
						
							|  |  |  |  |     existingUser, err := s.repo.FindByPhone(ctx, req.Phone) | 
					
						
							|  |  |  |  |     if err == nil && existingUser != nil { | 
					
						
							|  |  |  |  |         return nil, NewBusinessError(ErrPhoneExists) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证验证码 | 
					
						
							|  |  |  |  |     if err := s.smsCodeService.VerifyCode(ctx, req.Phone, req.Code, entities.SMSSceneRegister); err != nil { | 
					
						
							|  |  |  |  |         if strings.Contains(err.Error(), "expired") { | 
					
						
							|  |  |  |  |             return nil, NewBusinessError(ErrCodeExpired) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return nil, NewBusinessError(ErrInvalidCode) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 创建用户... | 
					
						
							|  |  |  |  |     return user, nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Handler层错误处理 | 
					
						
							|  |  |  |  | func (h *UserHandler) GetProfile(c *gin.Context) { | 
					
						
							|  |  |  |  |     userID := h.getCurrentUserID(c) | 
					
						
							|  |  |  |  |     if userID == "" { | 
					
						
							|  |  |  |  |         h.response.Unauthorized(c, ErrorMessages[ErrUnauthorized]) | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     user, err := h.userService.GetByID(c.Request.Context(), userID) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         if bizErr, ok := err.(*BusinessError); ok { | 
					
						
							|  |  |  |  |             switch bizErr.Code { | 
					
						
							|  |  |  |  |             case ErrUserNotFound: | 
					
						
							|  |  |  |  |                 h.response.NotFound(c, bizErr.Message) | 
					
						
							|  |  |  |  |             case ErrUnauthorized: | 
					
						
							|  |  |  |  |                 h.response.Unauthorized(c, bizErr.Message) | 
					
						
							|  |  |  |  |             case ErrForbidden: | 
					
						
							|  |  |  |  |                 h.response.Forbidden(c, bizErr.Message) | 
					
						
							|  |  |  |  |             default: | 
					
						
							|  |  |  |  |                 h.response.InternalError(c, bizErr.Message) | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             h.logger.Error("获取用户信息失败", zap.Error(err)) | 
					
						
							|  |  |  |  |             h.response.InternalError(c, ErrorMessages[ErrInternalServer]) | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     response := dto.FromEntity(user) | 
					
						
							|  |  |  |  |     h.response.Success(c, response, "获取用户信息成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 登录错误处理示例 | 
					
						
							|  |  |  |  | func (h *UserHandler) LoginWithPassword(c *gin.Context) { | 
					
						
							|  |  |  |  |     var req dto.LoginWithPasswordRequest | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if err := h.validator.BindAndValidate(c, &req); err != nil { | 
					
						
							|  |  |  |  |         return // 验证器已处理响应 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     user, err := h.userService.LoginWithPassword(c.Request.Context(), &req) | 
					
						
							|  |  |  |  |     if err != nil { | 
					
						
							|  |  |  |  |         h.logger.Error("用户登录失败", zap.Error(err), zap.String("phone", req.Phone)) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if bizErr, ok := err.(*BusinessError); ok { | 
					
						
							|  |  |  |  |             switch bizErr.Code { | 
					
						
							|  |  |  |  |             case ErrUserNotFound: | 
					
						
							|  |  |  |  |                 h.response.NotFound(c, "手机号未注册") | 
					
						
							|  |  |  |  |             case ErrInvalidPassword: | 
					
						
							|  |  |  |  |                 h.response.Unauthorized(c, "密码错误") | 
					
						
							|  |  |  |  |             case ErrUserBlocked: | 
					
						
							|  |  |  |  |                 h.response.Forbidden(c, bizErr.Message) | 
					
						
							|  |  |  |  |             default: | 
					
						
							|  |  |  |  |                 h.response.BadRequest(c, bizErr.Message) | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } else { | 
					
						
							|  |  |  |  |             h.response.InternalError(c, "登录失败,请稍后重试") | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         return | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 生成JWT token... | 
					
						
							|  |  |  |  |     h.response.Success(c, loginResponse, "登录成功") | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 统一错误响应格式 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 错误响应中间件 | 
					
						
							|  |  |  |  | func ErrorHandlerMiddleware() gin.HandlerFunc { | 
					
						
							|  |  |  |  |     return func(c *gin.Context) { | 
					
						
							|  |  |  |  |         c.Next() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 检查是否有未处理的错误 | 
					
						
							|  |  |  |  |         if len(c.Errors) > 0 { | 
					
						
							|  |  |  |  |             err := c.Errors.Last().Err | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if bizErr, ok := err.(*BusinessError); ok { | 
					
						
							|  |  |  |  |                 // 业务错误 | 
					
						
							|  |  |  |  |                 c.JSON(getHTTPStatus(bizErr.Code), gin.H{ | 
					
						
							|  |  |  |  |                     "success":    false, | 
					
						
							|  |  |  |  |                     "message":    bizErr.Message, | 
					
						
							|  |  |  |  |                     "error_code": bizErr.Code, | 
					
						
							|  |  |  |  |                     "details":    bizErr.Details, | 
					
						
							|  |  |  |  |                     "request_id": c.GetString("request_id"), | 
					
						
							|  |  |  |  |                     "timestamp":  time.Now().Unix(), | 
					
						
							|  |  |  |  |                 }) | 
					
						
							|  |  |  |  |             } else { | 
					
						
							|  |  |  |  |                 // 系统错误 | 
					
						
							|  |  |  |  |                 c.JSON(500, gin.H{ | 
					
						
							|  |  |  |  |                     "success":    false, | 
					
						
							|  |  |  |  |                     "message":    ErrorMessages[ErrInternalServer], | 
					
						
							|  |  |  |  |                     "error_code": ErrInternalServer, | 
					
						
							|  |  |  |  |                     "request_id": c.GetString("request_id"), | 
					
						
							|  |  |  |  |                     "timestamp":  time.Now().Unix(), | 
					
						
							|  |  |  |  |                 }) | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 根据错误码获取HTTP状态码 | 
					
						
							|  |  |  |  | func getHTTPStatus(errorCode string) int { | 
					
						
							|  |  |  |  |     statusMap := map[string]int{ | 
					
						
							|  |  |  |  |         ErrValidationFailed:    400, // Bad Request | 
					
						
							|  |  |  |  |         ErrInvalidRequest:      400, | 
					
						
							|  |  |  |  |         ErrMissingParam:        400, | 
					
						
							|  |  |  |  |         ErrInvalidCode:         400, | 
					
						
							|  |  |  |  |         ErrPhoneExists:         409, // Conflict | 
					
						
							|  |  |  |  |         ErrUserExists:          409, | 
					
						
							|  |  |  |  |         ErrUnauthorized:        401, // Unauthorized | 
					
						
							|  |  |  |  |         ErrTokenExpired:        401, | 
					
						
							|  |  |  |  |         ErrTokenInvalid:        401, | 
					
						
							|  |  |  |  |         ErrInvalidCredentials:  401, | 
					
						
							|  |  |  |  |         ErrForbidden:           403, // Forbidden | 
					
						
							|  |  |  |  |         ErrUserBlocked:         403, | 
					
						
							|  |  |  |  |         ErrUserNotFound:        404, // Not Found | 
					
						
							|  |  |  |  |         ErrCodeSendTooFrequent: 429, // Too Many Requests | 
					
						
							|  |  |  |  |         ErrRateLimitExceeded:   429, | 
					
						
							|  |  |  |  |         ErrInternalServer:      500, // Internal Server Error | 
					
						
							|  |  |  |  |         ErrServiceUnavailable:  503, // Service Unavailable | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if status, exists := statusMap[errorCode]; exists { | 
					
						
							|  |  |  |  |         return status | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return 500 // 默认服务器错误 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📈 日志记录规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 结构化日志 (中文日志消息) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 成功日志 | 
					
						
							|  |  |  |  | h.logger.Info("用户注册成功", | 
					
						
							|  |  |  |  |     zap.String("user_id", user.ID), | 
					
						
							|  |  |  |  |     zap.String("phone", user.Phone), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | h.logger.Info("用户登录成功", | 
					
						
							|  |  |  |  |     zap.String("user_id", user.ID), | 
					
						
							|  |  |  |  |     zap.String("phone", user.Phone), | 
					
						
							|  |  |  |  |     zap.String("login_method", "password"), | 
					
						
							|  |  |  |  |     zap.String("ip_address", c.ClientIP()), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | h.logger.Info("验证码发送成功", | 
					
						
							|  |  |  |  |     zap.String("phone", req.Phone), | 
					
						
							|  |  |  |  |     zap.String("scene", string(req.Scene)), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 错误日志 | 
					
						
							|  |  |  |  | h.logger.Error("用户注册失败", | 
					
						
							|  |  |  |  |     zap.Error(err), | 
					
						
							|  |  |  |  |     zap.String("phone", req.Phone), | 
					
						
							|  |  |  |  |     zap.String("error_type", "business_logic"), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | h.logger.Error("数据库操作失败", | 
					
						
							|  |  |  |  |     zap.Error(err), | 
					
						
							|  |  |  |  |     zap.String("operation", "create_user"), | 
					
						
							|  |  |  |  |     zap.String("table", "users"), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | h.logger.Error("外部服务调用失败", | 
					
						
							|  |  |  |  |     zap.Error(err), | 
					
						
							|  |  |  |  |     zap.String("service", "sms_service"), | 
					
						
							|  |  |  |  |     zap.String("action", "send_code"), | 
					
						
							|  |  |  |  |     zap.String("phone", req.Phone), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 警告日志 | 
					
						
							|  |  |  |  | h.logger.Warn("验证码重复发送", | 
					
						
							|  |  |  |  |     zap.String("phone", req.Phone), | 
					
						
							|  |  |  |  |     zap.String("scene", string(req.Scene)), | 
					
						
							|  |  |  |  |     zap.Int("retry_count", retryCount), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | h.logger.Warn("异常登录尝试", | 
					
						
							|  |  |  |  |     zap.String("phone", req.Phone), | 
					
						
							|  |  |  |  |     zap.String("ip_address", c.ClientIP()), | 
					
						
							|  |  |  |  |     zap.String("user_agent", c.GetHeader("User-Agent")), | 
					
						
							|  |  |  |  |     zap.Int("attempt_count", attemptCount), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 调试日志 | 
					
						
							|  |  |  |  | h.logger.Debug("开始处理用户注册请求", | 
					
						
							|  |  |  |  |     zap.String("phone", req.Phone), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 日志级别使用规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   **Debug**: 详细的调试信息(开发环境) | 
					
						
							|  |  |  |  |     -   请求参数详情 | 
					
						
							|  |  |  |  |     -   中间步骤状态 | 
					
						
							|  |  |  |  |     -   性能指标数据 | 
					
						
							|  |  |  |  | -   **Info**: 重要的业务信息(生产环境) | 
					
						
							|  |  |  |  |     -   用户操作成功记录 | 
					
						
							|  |  |  |  |     -   系统状态变更 | 
					
						
							|  |  |  |  |     -   业务流程关键节点 | 
					
						
							|  |  |  |  | -   **Warn**: 需要关注但不影响主功能的问题 | 
					
						
							|  |  |  |  |     -   重试操作 | 
					
						
							|  |  |  |  |     -   降级处理 | 
					
						
							|  |  |  |  |     -   资源使用超预期 | 
					
						
							|  |  |  |  | -   **Error**: 影响功能的错误信息 | 
					
						
							|  |  |  |  |     -   业务逻辑错误 | 
					
						
							|  |  |  |  |     -   数据库操作失败 | 
					
						
							|  |  |  |  |     -   外部服务调用失败 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 日志上下文信息规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 必需字段 | 
					
						
							|  |  |  |  | - request_id: 请求追踪ID | 
					
						
							|  |  |  |  | - user_id: 用户ID(如果已认证) | 
					
						
							|  |  |  |  | - action: 操作类型 | 
					
						
							|  |  |  |  | - timestamp: 时间戳(自动添加) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 可选字段 | 
					
						
							|  |  |  |  | - phone: 手机号(敏感信息需脱敏) | 
					
						
							|  |  |  |  | - ip_address: 客户端IP | 
					
						
							|  |  |  |  | - user_agent: 用户代理 | 
					
						
							|  |  |  |  | - error_type: 错误类型分类 | 
					
						
							|  |  |  |  | - duration: 操作耗时 | 
					
						
							|  |  |  |  | - service: 服务名称 | 
					
						
							|  |  |  |  | - method: 请求方法 | 
					
						
							|  |  |  |  | - path: 请求路径 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 脱敏处理示例 | 
					
						
							|  |  |  |  | func maskPhone(phone string) string { | 
					
						
							|  |  |  |  |     if len(phone) != 11 { | 
					
						
							|  |  |  |  |         return phone | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     return phone[:3] + "****" + phone[7:] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | h.logger.Info("用户登录成功", | 
					
						
							|  |  |  |  |     zap.String("phone", maskPhone(user.Phone)), // 138****8000 | 
					
						
							|  |  |  |  |     zap.String("user_id", user.ID), | 
					
						
							|  |  |  |  |     zap.String("request_id", c.GetString("request_id"))) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🧪 测试规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 单元测试 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | func TestUserService_Create(t *testing.T) { | 
					
						
							|  |  |  |  |     // 使用testify进行测试 | 
					
						
							|  |  |  |  |     assert := assert.New(t) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // Mock依赖 | 
					
						
							|  |  |  |  |     mockRepo := &mocks.UserRepository{} | 
					
						
							|  |  |  |  |     mockEventBus := &mocks.EventBus{} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     service := services.NewUserService(mockRepo, mockEventBus, logger) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 测试用例... | 
					
						
							|  |  |  |  |     user, err := service.Create(ctx, req) | 
					
						
							|  |  |  |  |     assert.NoError(err) | 
					
						
							|  |  |  |  |     assert.NotNil(user) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 集成测试 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | func TestUserHandler_Create(t *testing.T) { | 
					
						
							|  |  |  |  |     // 设置测试环境 | 
					
						
							|  |  |  |  |     router := setupTestRouter() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 发送测试请求 | 
					
						
							|  |  |  |  |     w := httptest.NewRecorder() | 
					
						
							|  |  |  |  |     req, _ := http.NewRequest("POST", "/api/v1/users", bytes.NewBuffer(jsonData)) | 
					
						
							|  |  |  |  |     router.ServeHTTP(w, req) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 验证响应 | 
					
						
							|  |  |  |  |     assert.Equal(t, 201, w.Code) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🚀 新增业务领域开发指南 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 创建新领域 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 1. 创建领域目录结构 | 
					
						
							|  |  |  |  | mkdir -p internal/domains/product/{dto,entities,events,handlers,repositories,routes,services,validators} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 2. 复制用户领域作为模板 | 
					
						
							|  |  |  |  | cp -r internal/domains/user/* internal/domains/product/ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 3. 修改包名和结构体名称 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 注册到依赖注入容器 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/container/container.go | 
					
						
							|  |  |  |  | fx.Provide( | 
					
						
							|  |  |  |  |     // Product domain | 
					
						
							|  |  |  |  |     NewProductRepository, | 
					
						
							|  |  |  |  |     NewProductService, | 
					
						
							|  |  |  |  |     NewProductHandler, | 
					
						
							|  |  |  |  |     NewProductRoutes, | 
					
						
							|  |  |  |  | ), | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | fx.Invoke( | 
					
						
							|  |  |  |  |     RegisterProductRoutes, | 
					
						
							|  |  |  |  | ), | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 添加路由注册 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | func RegisterProductRoutes( | 
					
						
							|  |  |  |  |     router *http.GinRouter, | 
					
						
							|  |  |  |  |     productRoutes *routes.ProductRoutes, | 
					
						
							|  |  |  |  | ) { | 
					
						
							|  |  |  |  |     productRoutes.RegisterRoutes(router.GetEngine()) | 
					
						
							|  |  |  |  |     productRoutes.RegisterPublicRoutes(router.GetEngine()) | 
					
						
							|  |  |  |  |     productRoutes.RegisterAdminRoutes(router.GetEngine()) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🚀 DDD 新域开发指南 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 创建新业务域 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 1. 创建领域目录结构(以订单域为例) | 
					
						
							|  |  |  |  | mkdir -p internal/domains/order/{dto,entities,events,handlers,repositories,routes,services} | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 2. 复制用户域作为模板 | 
					
						
							|  |  |  |  | cp -r internal/domains/user/* internal/domains/order/ | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 3. 批量替换包名和结构体名称 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 定义领域实体和 DTO | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/domains/order/entities/order.go | 
					
						
							|  |  |  |  | type Order struct { | 
					
						
							|  |  |  |  |     ID          string    `json:"id" gorm:"primaryKey"` | 
					
						
							|  |  |  |  |     UserID      string    `json:"user_id" gorm:"not null"` | 
					
						
							|  |  |  |  |     TotalAmount float64   `json:"total_amount"` | 
					
						
							|  |  |  |  |     Status      Status    `json:"status"` | 
					
						
							|  |  |  |  |     CreatedAt   time.Time `json:"created_at"` | 
					
						
							|  |  |  |  |     UpdatedAt   time.Time `json:"updated_at"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // internal/domains/order/dto/order_dto.go | 
					
						
							|  |  |  |  | type CreateOrderRequest struct { | 
					
						
							|  |  |  |  |     Items []OrderItem `json:"items" binding:"required,dive"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | type OrderResponse struct { | 
					
						
							|  |  |  |  |     ID          string    `json:"id" example:"123e4567-e89b-12d3-a456-426614174000"` | 
					
						
							|  |  |  |  |     UserID      string    `json:"user_id" example:"user-123"` | 
					
						
							|  |  |  |  |     TotalAmount float64   `json:"total_amount" example:"99.99"` | 
					
						
							|  |  |  |  |     Status      string    `json:"status" example:"pending"` | 
					
						
							|  |  |  |  |     CreatedAt   time.Time `json:"created_at" example:"2024-01-01T00:00:00Z"` | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. 配置领域路由 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/domains/order/routes/order_routes.go | 
					
						
							|  |  |  |  | func (r *OrderRoutes) RegisterRoutes(router *gin.Engine) { | 
					
						
							|  |  |  |  |     v1 := router.Group("/api/v1") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // 📦 订单域路由组 | 
					
						
							|  |  |  |  |     orders := v1.Group("/orders") | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         // 公开查询(可选认证) | 
					
						
							|  |  |  |  |         orders.GET("/:id/public", r.handler.GetPublicOrder) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         // 需要认证的路由 | 
					
						
							|  |  |  |  |         authenticated := orders.Group("") | 
					
						
							|  |  |  |  |         authenticated.Use(r.jwtAuth.Handle()) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             authenticated.GET("", r.handler.List)              // GET /api/v1/orders | 
					
						
							|  |  |  |  |             authenticated.POST("", r.handler.Create)           // POST /api/v1/orders | 
					
						
							|  |  |  |  |             authenticated.GET("/:id", r.handler.GetByID)       // GET /api/v1/orders/:id | 
					
						
							|  |  |  |  |             authenticated.PUT("/:id", r.handler.Update)        // PUT /api/v1/orders/:id | 
					
						
							|  |  |  |  |             authenticated.POST("/:id/cancel", r.handler.Cancel) // POST /api/v1/orders/:id/cancel | 
					
						
							|  |  |  |  |             authenticated.GET("/:id/items", r.handler.GetItems) // GET /api/v1/orders/:id/items | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. 注册到依赖注入容器 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // internal/container/container.go | 
					
						
							|  |  |  |  | fx.Provide( | 
					
						
							|  |  |  |  |     // User domain | 
					
						
							|  |  |  |  |     repositories.NewUserRepository, | 
					
						
							|  |  |  |  |     services.NewUserService, | 
					
						
							|  |  |  |  |     handlers.NewUserHandler, | 
					
						
							|  |  |  |  |     routes.NewUserRoutes, | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     // Order domain - 新增 | 
					
						
							|  |  |  |  |     order_repositories.NewOrderRepository, | 
					
						
							|  |  |  |  |     order_services.NewOrderService, | 
					
						
							|  |  |  |  |     order_handlers.NewOrderHandler, | 
					
						
							|  |  |  |  |     order_routes.NewOrderRoutes, | 
					
						
							|  |  |  |  | ), | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | fx.Invoke( | 
					
						
							|  |  |  |  |     RegisterUserRoutes, | 
					
						
							|  |  |  |  |     RegisterOrderRoutes, // 新增 | 
					
						
							|  |  |  |  | ), | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 添加路由注册函数 | 
					
						
							|  |  |  |  | func RegisterOrderRoutes( | 
					
						
							|  |  |  |  |     router *http.GinRouter, | 
					
						
							|  |  |  |  |     orderRoutes *order_routes.OrderRoutes, | 
					
						
							|  |  |  |  | ) { | 
					
						
							|  |  |  |  |     orderRoutes.RegisterRoutes(router.GetEngine()) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 5. 跨域关系处理 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 用户订单关系 - 在用户域添加 | 
					
						
							|  |  |  |  | func (r *UserRoutes) RegisterRoutes(router *gin.Engine) { | 
					
						
							|  |  |  |  |     users := v1.Group("/users") | 
					
						
							|  |  |  |  |     authenticated := users.Group("") | 
					
						
							|  |  |  |  |     authenticated.Use(r.jwtAuth.Handle()) | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         authenticated.GET("/me", r.handler.GetProfile) | 
					
						
							|  |  |  |  |         // 添加用户相关的订单操作 | 
					
						
							|  |  |  |  |         authenticated.GET("/me/orders", r.handler.GetUserOrders)     // 获取用户订单 | 
					
						
							|  |  |  |  |         authenticated.GET("/me/orders/stats", r.handler.GetOrderStats) // 订单统计 | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 或者在订单域处理用户关系 | 
					
						
							|  |  |  |  | func (h *OrderHandler) List(c *gin.Context) { | 
					
						
							|  |  |  |  |     userID := h.getCurrentUserID(c) // 从JWT中获取用户ID | 
					
						
							|  |  |  |  |     orders, err := h.orderService.GetUserOrders(ctx, userID) | 
					
						
							|  |  |  |  |     // ... 业务逻辑 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📖 Swagger/OpenAPI 文档集成指南 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 新增接口 Swagger 文档支持 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 为 Handler 方法添加 Swagger 注释 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // @Summary 接口简短描述(必需) | 
					
						
							|  |  |  |  | // @Description 接口详细描述(可选) | 
					
						
							|  |  |  |  | // @Tags 标签分组(推荐) | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce json | 
					
						
							|  |  |  |  | // @Security Bearer  # 如果需要JWT认证 | 
					
						
							|  |  |  |  | // @Param request body dto.RequestStruct true "请求参数描述" | 
					
						
							|  |  |  |  | // @Param id path string true "路径参数描述" | 
					
						
							|  |  |  |  | // @Param page query int false "查询参数描述" | 
					
						
							|  |  |  |  | // @Success 200 {object} dto.ResponseStruct "成功响应描述" | 
					
						
							|  |  |  |  | // @Failure 400 {object} map[string]interface{} "错误响应描述" | 
					
						
							|  |  |  |  | // @Router /api/v1/your-endpoint [post] | 
					
						
							|  |  |  |  | func (h *YourHandler) YourMethod(c *gin.Context) { | 
					
						
							|  |  |  |  |     // Handler实现 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### Swagger 注释语法详解 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 基础注释 | 
					
						
							|  |  |  |  | // @Summary        接口摘要(在文档列表中显示) | 
					
						
							|  |  |  |  | // @Description    详细描述(支持多行) | 
					
						
							|  |  |  |  | // @Tags           标签分组(用于在UI中分组显示) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 请求/响应格式 | 
					
						
							|  |  |  |  | // @Accept         接受的内容类型:json, xml, plain, html, mpfd, x-www-form-urlencoded | 
					
						
							|  |  |  |  | // @Produce        响应的内容类型:json, xml, plain, html | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 安全认证 | 
					
						
							|  |  |  |  | // @Security Bearer              # JWT认证 | 
					
						
							|  |  |  |  | // @Security ApiKeyAuth          # API Key认证 | 
					
						
							|  |  |  |  | // @Security BasicAuth           # 基础认证 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 参数定义 | 
					
						
							|  |  |  |  | // @Param name location type required "description" Enums(A,B,C) default(A) | 
					
						
							|  |  |  |  | // location: query, path, header, body, formData | 
					
						
							|  |  |  |  | // type: string, number, integer, boolean, array, object | 
					
						
							|  |  |  |  | // required: true, false | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 响应定义 | 
					
						
							|  |  |  |  | // @Success code {type} model "description" | 
					
						
							|  |  |  |  | // @Failure code {type} model "description" | 
					
						
							|  |  |  |  | // code: HTTP状态码 | 
					
						
							|  |  |  |  | // type: object, array, string, number, boolean | 
					
						
							|  |  |  |  | // model: 响应模型(如dto.UserResponse) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 路由定义 | 
					
						
							|  |  |  |  | // @Router path [method] | 
					
						
							|  |  |  |  | // method: get, post, put, delete, patch, head, options | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 完整示例:订单域接口文档 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // CreateOrder 创建订单 | 
					
						
							|  |  |  |  | // @Summary 创建新订单 | 
					
						
							|  |  |  |  | // @Description 根据购物车内容创建新的订单,支持多商品下单 | 
					
						
							|  |  |  |  | // @Tags 订单管理 | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce json | 
					
						
							|  |  |  |  | // @Security Bearer | 
					
						
							|  |  |  |  | // @Param request body dto.CreateOrderRequest true "创建订单请求" | 
					
						
							|  |  |  |  | // @Success 201 {object} dto.OrderResponse "订单创建成功" | 
					
						
							|  |  |  |  | // @Failure 400 {object} map[string]interface{} "请求参数错误" | 
					
						
							|  |  |  |  | // @Failure 401 {object} map[string]interface{} "未认证" | 
					
						
							|  |  |  |  | // @Failure 422 {object} map[string]interface{} "业务验证失败" | 
					
						
							|  |  |  |  | // @Failure 500 {object} map[string]interface{} "服务器内部错误" | 
					
						
							|  |  |  |  | // @Router /api/v1/orders [post] | 
					
						
							|  |  |  |  | func (h *OrderHandler) CreateOrder(c *gin.Context) { | 
					
						
							|  |  |  |  |     // 实现代码 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetOrderList 获取订单列表 | 
					
						
							|  |  |  |  | // @Summary 获取当前用户的订单列表 | 
					
						
							|  |  |  |  | // @Description 分页获取当前用户的订单列表,支持按状态筛选和关键词搜索 | 
					
						
							|  |  |  |  | // @Tags 订单管理 | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce json | 
					
						
							|  |  |  |  | // @Security Bearer | 
					
						
							|  |  |  |  | // @Param page query int false "页码" default(1) minimum(1) | 
					
						
							|  |  |  |  | // @Param page_size query int false "每页数量" default(20) minimum(1) maximum(100) | 
					
						
							|  |  |  |  | // @Param status query string false "订单状态" Enums(pending,paid,shipped,delivered,cancelled) | 
					
						
							|  |  |  |  | // @Param search query string false "搜索关键词" | 
					
						
							|  |  |  |  | // @Success 200 {object} dto.OrderListResponse "订单列表" | 
					
						
							|  |  |  |  | // @Failure 400 {object} map[string]interface{} "请求参数错误" | 
					
						
							|  |  |  |  | // @Failure 401 {object} map[string]interface{} "未认证" | 
					
						
							|  |  |  |  | // @Failure 500 {object} map[string]interface{} "服务器内部错误" | 
					
						
							|  |  |  |  | // @Router /api/v1/orders [get] | 
					
						
							|  |  |  |  | func (h *OrderHandler) GetOrderList(c *gin.Context) { | 
					
						
							|  |  |  |  |     // 实现代码 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UpdateOrder 更新订单 | 
					
						
							|  |  |  |  | // @Summary 更新订单信息 | 
					
						
							|  |  |  |  | // @Description 更新指定订单的部分信息,如收货地址、备注等 | 
					
						
							|  |  |  |  | // @Tags 订单管理 | 
					
						
							|  |  |  |  | // @Accept json | 
					
						
							|  |  |  |  | // @Produce json | 
					
						
							|  |  |  |  | // @Security Bearer | 
					
						
							|  |  |  |  | // @Param id path string true "订单ID" Format(uuid) | 
					
						
							|  |  |  |  | // @Param request body dto.UpdateOrderRequest true "更新订单请求" | 
					
						
							|  |  |  |  | // @Success 200 {object} dto.OrderResponse "订单更新成功" | 
					
						
							|  |  |  |  | // @Failure 400 {object} map[string]interface{} "请求参数错误" | 
					
						
							|  |  |  |  | // @Failure 401 {object} map[string]interface{} "未认证" | 
					
						
							|  |  |  |  | // @Failure 403 {object} map[string]interface{} "无权限操作此订单" | 
					
						
							|  |  |  |  | // @Failure 404 {object} map[string]interface{} "订单不存在" | 
					
						
							|  |  |  |  | // @Failure 500 {object} map[string]interface{} "服务器内部错误" | 
					
						
							|  |  |  |  | // @Router /api/v1/orders/{id} [put] | 
					
						
							|  |  |  |  | func (h *OrderHandler) UpdateOrder(c *gin.Context) { | 
					
						
							|  |  |  |  |     // 实现代码 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. DTO 结构体文档化 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 为请求/响应结构体添加文档标签 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // CreateOrderRequest 创建订单请求 | 
					
						
							|  |  |  |  | type CreateOrderRequest struct { | 
					
						
							|  |  |  |  |     Items           []OrderItem `json:"items" binding:"required,dive" example:"[{\"product_id\":\"123\",\"quantity\":2}]"` | 
					
						
							|  |  |  |  |     DeliveryAddress string      `json:"delivery_address" binding:"required,max=200" example:"北京市朝阳区xxx街道xxx号"` | 
					
						
							|  |  |  |  |     PaymentMethod   string      `json:"payment_method" binding:"required,oneof=alipay wechat" example:"alipay"` | 
					
						
							|  |  |  |  |     Remark          string      `json:"remark" binding:"max=500" example:"请尽快发货"` | 
					
						
							|  |  |  |  | } // @name CreateOrderRequest | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // OrderResponse 订单响应 | 
					
						
							|  |  |  |  | type OrderResponse struct { | 
					
						
							|  |  |  |  |     ID              string      `json:"id" example:"123e4567-e89b-12d3-a456-426614174000"` | 
					
						
							|  |  |  |  |     UserID          string      `json:"user_id" example:"user-123"` | 
					
						
							|  |  |  |  |     OrderNo         string      `json:"order_no" example:"ORD20240101001"` | 
					
						
							|  |  |  |  |     Status          OrderStatus `json:"status" example:"pending"` | 
					
						
							|  |  |  |  |     TotalAmount     float64     `json:"total_amount" example:"299.99"` | 
					
						
							|  |  |  |  |     PaymentMethod   string      `json:"payment_method" example:"alipay"` | 
					
						
							|  |  |  |  |     DeliveryAddress string      `json:"delivery_address" example:"北京市朝阳区xxx街道xxx号"` | 
					
						
							|  |  |  |  |     Items           []OrderItem `json:"items"` | 
					
						
							|  |  |  |  |     CreatedAt       time.Time   `json:"created_at" example:"2024-01-01T00:00:00Z"` | 
					
						
							|  |  |  |  |     UpdatedAt       time.Time   `json:"updated_at" example:"2024-01-01T00:00:00Z"` | 
					
						
							|  |  |  |  | } // @name OrderResponse | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // OrderItem 订单商品项 | 
					
						
							|  |  |  |  | type OrderItem struct { | 
					
						
							|  |  |  |  |     ProductID   string  `json:"product_id" example:"prod-123"` | 
					
						
							|  |  |  |  |     ProductName string  `json:"product_name" example:"iPhone 15 Pro"` | 
					
						
							|  |  |  |  |     Quantity    int     `json:"quantity" example:"1"` | 
					
						
							|  |  |  |  |     Price       float64 `json:"price" example:"999.99"` | 
					
						
							|  |  |  |  |     Subtotal    float64 `json:"subtotal" example:"999.99"` | 
					
						
							|  |  |  |  | } // @name OrderItem | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // OrderListResponse 订单列表响应 | 
					
						
							|  |  |  |  | type OrderListResponse struct { | 
					
						
							|  |  |  |  |     Orders     []OrderResponse `json:"orders"` | 
					
						
							|  |  |  |  |     Pagination Pagination      `json:"pagination"` | 
					
						
							|  |  |  |  | } // @name OrderListResponse | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Pagination 分页信息 | 
					
						
							|  |  |  |  | type Pagination struct { | 
					
						
							|  |  |  |  |     Page       int `json:"page" example:"1"` | 
					
						
							|  |  |  |  |     PageSize   int `json:"page_size" example:"20"` | 
					
						
							|  |  |  |  |     Total      int `json:"total" example:"150"` | 
					
						
							|  |  |  |  |     TotalPages int `json:"total_pages" example:"8"` | 
					
						
							|  |  |  |  | } // @name Pagination | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 枚举类型文档化 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // OrderStatus 订单状态 | 
					
						
							|  |  |  |  | type OrderStatus string | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | const ( | 
					
						
							|  |  |  |  |     OrderStatusPending   OrderStatus = "pending"   // 待支付 | 
					
						
							|  |  |  |  |     OrderStatusPaid      OrderStatus = "paid"      // 已支付 | 
					
						
							|  |  |  |  |     OrderStatusShipped   OrderStatus = "shipped"   // 已发货 | 
					
						
							|  |  |  |  |     OrderStatusDelivered OrderStatus = "delivered" // 已送达 | 
					
						
							|  |  |  |  |     OrderStatusCancelled OrderStatus = "cancelled" // 已取消 | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 为枚举添加Swagger文档 | 
					
						
							|  |  |  |  | // @Description 订单状态 | 
					
						
							|  |  |  |  | // @Enum pending,paid,shipped,delivered,cancelled | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. 文档生成和更新流程 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 标准工作流程 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 1. 编写/修改Handler方法,添加Swagger注释 | 
					
						
							|  |  |  |  | vim internal/domains/order/handlers/order_handler.go | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 2. 编写/修改DTO结构体,添加example标签 | 
					
						
							|  |  |  |  | vim internal/domains/order/dto/order_dto.go | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 3. 重新生成Swagger文档 | 
					
						
							|  |  |  |  | make docs | 
					
						
							|  |  |  |  | # 或直接使用命令 | 
					
						
							|  |  |  |  | swag init -g cmd/api/main.go -o docs/swagger | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 4. 重启项目 | 
					
						
							|  |  |  |  | go run cmd/api/main.go | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 5. 访问文档查看效果 | 
					
						
							|  |  |  |  | open http://localhost:8080/swagger/index.html | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 快速开发脚本 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 创建docs脚本:scripts/update-docs.sh | 
					
						
							|  |  |  |  | #!/bin/bash | 
					
						
							|  |  |  |  | echo "🔄 Updating Swagger documentation..." | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 生成文档 | 
					
						
							|  |  |  |  | make docs | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | if [ $? -eq 0 ]; then | 
					
						
							|  |  |  |  |     echo "✅ Swagger documentation updated successfully!" | 
					
						
							|  |  |  |  |     echo "📖 View at: http://localhost:8080/swagger/index.html" | 
					
						
							|  |  |  |  | else | 
					
						
							|  |  |  |  |     echo "❌ Failed to update documentation" | 
					
						
							|  |  |  |  |     exit 1 | 
					
						
							|  |  |  |  | fi | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 重启开发服务器(可选) | 
					
						
							|  |  |  |  | if [ "$1" = "--restart" ]; then | 
					
						
							|  |  |  |  |     echo "🔄 Restarting development server..." | 
					
						
							|  |  |  |  |     pkill -f "go run cmd/api/main.go" | 
					
						
							|  |  |  |  |     nohup go run cmd/api/main.go > /dev/null 2>&1 & | 
					
						
							|  |  |  |  |     echo "🚀 Development server restarted!" | 
					
						
							|  |  |  |  | fi | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 5. 文档质量检查清单 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 必需元素检查 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   [ ] **@Summary**: 简洁明了的接口描述 | 
					
						
							|  |  |  |  | -   [ ] **@Description**: 详细的功能说明 | 
					
						
							|  |  |  |  | -   [ ] **@Tags**: 正确的分组标签 | 
					
						
							|  |  |  |  | -   [ ] **@Router**: 正确的路径和 HTTP 方法 | 
					
						
							|  |  |  |  | -   [ ] **@Accept/@Produce**: 正确的内容类型 | 
					
						
							|  |  |  |  | -   [ ] **@Security**: 认证要求(如需要) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 参数文档检查 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   [ ] **路径参数**: 所有{id}等路径参数都有@Param | 
					
						
							|  |  |  |  | -   [ ] **查询参数**: 分页、筛选等参数都有@Param | 
					
						
							|  |  |  |  | -   [ ] **请求体**: 复杂请求有@Param body 定义 | 
					
						
							|  |  |  |  | -   [ ] **示例值**: 所有参数都有 realistic 的 example | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 响应文档检查 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   [ ] **成功响应**: @Success 定义了正确的状态码和模型 | 
					
						
							|  |  |  |  | -   [ ] **错误响应**: @Failure 覆盖了主要的错误场景 | 
					
						
							|  |  |  |  | -   [ ] **响应模型**: DTO 结构体有完整的 json 标签和 example | 
					
						
							|  |  |  |  | -   [ ] **状态码**: 符合 RESTful 规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 6. 高级文档特性 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 自定义响应模型 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 为复杂响应创建专门的文档模型 | 
					
						
							|  |  |  |  | type APIResponse struct { | 
					
						
							|  |  |  |  |     Success   bool        `json:"success" example:"true"` | 
					
						
							|  |  |  |  |     Data      interface{} `json:"data"` | 
					
						
							|  |  |  |  |     Message   string      `json:"message" example:"操作成功"` | 
					
						
							|  |  |  |  |     RequestID string      `json:"request_id" example:"req-123"` | 
					
						
							|  |  |  |  |     Timestamp int64       `json:"timestamp" example:"1640995200"` | 
					
						
							|  |  |  |  | } // @name APIResponse | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 在Handler中使用 | 
					
						
							|  |  |  |  | // @Success 200 {object} APIResponse{data=dto.OrderResponse} "成功响应" | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 分组和版本管理 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 使用一致的标签分组 | 
					
						
							|  |  |  |  | // @Tags 用户认证    # 认证相关接口 | 
					
						
							|  |  |  |  | // @Tags 用户管理    # 用户CRUD接口 | 
					
						
							|  |  |  |  | // @Tags 订单管理    # 订单相关接口 | 
					
						
							|  |  |  |  | // @Tags 商品管理    # 商品相关接口 | 
					
						
							|  |  |  |  | // @Tags 系统管理    # 系统功能接口 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 版本控制 | 
					
						
							|  |  |  |  | // @Router /api/v1/users [post]  # V1版本 | 
					
						
							|  |  |  |  | // @Router /api/v2/users [post]  # V2版本(向后兼容) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 7. 常见问题和解决方案 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 问题 1:文档生成失败 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 检查Swagger注释语法 | 
					
						
							|  |  |  |  | swag init -g cmd/api/main.go -o docs/swagger --parseDependency | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 常见错误: | 
					
						
							|  |  |  |  | # - 缺少@Router注释 | 
					
						
							|  |  |  |  | # - HTTP方法写错(必须小写) | 
					
						
							|  |  |  |  | # - 路径格式不正确 | 
					
						
							|  |  |  |  | # - 缺少必需的包导入 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 问题 2:模型没有正确显示 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 确保结构体有正确的标签 | 
					
						
							|  |  |  |  | type UserRequest struct { | 
					
						
							|  |  |  |  |     Name string `json:"name" example:"张三"`  # json标签必需 | 
					
						
							|  |  |  |  | } // @name UserRequest  # 显式命名(可选) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 确保包被正确解析 | 
					
						
							|  |  |  |  | swag init -g cmd/api/main.go -o docs/swagger --parseDependency --parseInternal | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 问题 3:认证测试失败 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 确保安全定义正确 | 
					
						
							|  |  |  |  | // @securityDefinitions.apikey Bearer | 
					
						
							|  |  |  |  | // @in header | 
					
						
							|  |  |  |  | // @name Authorization | 
					
						
							|  |  |  |  | // @description Type "Bearer" followed by a space and JWT token. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 在接口中正确使用 | 
					
						
							|  |  |  |  | // @Security Bearer | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 8. 持续集成中的文档检查 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # CI脚本示例:.github/workflows/docs.yml | 
					
						
							|  |  |  |  | name: API Documentation Check | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | on: [push, pull_request] | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | jobs: | 
					
						
							|  |  |  |  |   docs-check: | 
					
						
							|  |  |  |  |     runs-on: ubuntu-latest | 
					
						
							|  |  |  |  |     steps: | 
					
						
							|  |  |  |  |     - uses: actions/checkout@v2 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - name: Setup Go | 
					
						
							|  |  |  |  |       uses: actions/setup-go@v2 | 
					
						
							|  |  |  |  |       with: | 
					
						
							|  |  |  |  |         go-version: 1.23 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - name: Install swag | 
					
						
							|  |  |  |  |       run: go install github.com/swaggo/swag/cmd/swag@latest | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - name: Generate docs | 
					
						
							|  |  |  |  |       run: make docs | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - name: Check docs are up to date | 
					
						
							|  |  |  |  |       run: | | 
					
						
							|  |  |  |  |         if [[ `git status --porcelain docs/` ]]; then | 
					
						
							|  |  |  |  |           echo "Documentation is out of date. Please run 'make docs'" | 
					
						
							|  |  |  |  |           exit 1 | 
					
						
							|  |  |  |  |         fi | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📚 最佳实践总结 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 🏗️ 架构设计原则 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 1. **领域驱动设计**: 按业务域组织代码和 API 路径,避免技术导向设计 | 
					
						
							|  |  |  |  | 2. **单一职责原则**: 每个层只负责自己的职责,保持清晰的边界分离 | 
					
						
							|  |  |  |  | 3. **依赖注入管理**: 使用 Uber FX 进行依赖管理,支持模块化扩展 | 
					
						
							|  |  |  |  | 4. **接口隔离原则**: 定义清晰的接口边界,便于测试和扩展 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 📋 API 设计规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 5. **统一响应格式**: 标准化的 API 响应结构和中文错误提示 | 
					
						
							|  |  |  |  | 6. **RESTful 路径设计**: 语义化路径清晰表达业务意图 | 
					
						
							|  |  |  |  | 7. **多层数据验证**: 从 DTO 到业务规则的完整验证链 | 
					
						
							|  |  |  |  | 8. **中文化用户体验**: 所有面向用户的消息都使用中文 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 🔧 技术实现规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 9. **结构化日志记录**: 使用 Zap 记录中文结构化日志,便于监控和调试 | 
					
						
							|  |  |  |  | 10. **智能缓存策略**: 合理使用 Redis 缓存提升系统性能 | 
					
						
							|  |  |  |  | 11. **事件驱动架构**: 使用领域事件解耦业务逻辑,支持异步处理 | 
					
						
							|  |  |  |  | 12. **错误处理分层**: 统一的业务错误码和 HTTP 状态码映射 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 📖 开发协作规范 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 13. **文档优先开发**: 编写接口时同步维护 Swagger 文档,确保文档和代码一致性 | 
					
						
							|  |  |  |  | 14. **完整测试覆盖**: 单元测试、集成测试和端到端测试 | 
					
						
							|  |  |  |  | 15. **代码审查机制**: 确保代码质量和规范一致性 | 
					
						
							|  |  |  |  | 16. **持续集成部署**: 自动化构建、测试和部署流程 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 🚀 性能和扩展性 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 17. **数据库事务管理**: 合理使用数据库事务确保数据一致性 | 
					
						
							|  |  |  |  | 18. **请求限流保护**: 防止恶意请求和系统过载 | 
					
						
							|  |  |  |  | 19. **监控和告警**: 完整的应用性能监控和业务指标收集 | 
					
						
							|  |  |  |  | 20. **水平扩展支持**: 微服务架构支持横向扩展 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🔄 配置管理 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. 环境配置 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```yaml | 
					
						
							|  |  |  |  | # config.yaml (开发环境) | 
					
						
							|  |  |  |  | server: | 
					
						
							|  |  |  |  |   port: "8080" | 
					
						
							|  |  |  |  |   mode: "debug" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # config.prod.yaml (生产环境) | 
					
						
							|  |  |  |  | server: | 
					
						
							|  |  |  |  |   port: "8080" | 
					
						
							|  |  |  |  |   mode: "release" | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. 环境变量覆盖 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 优先级: 环境变量 > 配置文件 > 默认值 | 
					
						
							|  |  |  |  | export ENV=production | 
					
						
							|  |  |  |  | export DB_HOST=prod-database | 
					
						
							|  |  |  |  | export JWT_SECRET=secure-jwt-secret | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📋 当前项目 API 接口清单 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 👥 用户域 (User Domain) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 🌍 公开接口(无需认证) | 
					
						
							|  |  |  |  | POST   /api/v1/users/send-code    # 发送验证码 | 
					
						
							|  |  |  |  | POST   /api/v1/users/register     # 用户注册 | 
					
						
							|  |  |  |  | POST   /api/v1/users/login        # 用户登录 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 🔐 认证接口(需要JWT Token) | 
					
						
							|  |  |  |  | GET    /api/v1/users/me           # 获取当前用户信息 | 
					
						
							|  |  |  |  | PUT    /api/v1/users/me/password  # 修改密码 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 📱 SMS 验证码域 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 🌍 公开接口 | 
					
						
							|  |  |  |  | POST   /api/v1/sms/send          # 发送验证码(与users/send-code相同) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 🔧 系统接口 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 🌍 健康检查 | 
					
						
							|  |  |  |  | GET    /health                   # 系统健康状态 | 
					
						
							|  |  |  |  | GET    /health/detailed          # 详细健康状态 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 📊 请求示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 发送验证码 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl -X POST http://localhost:8080/api/v1/users/send-code \ | 
					
						
							|  |  |  |  |   -H "Content-Type: application/json" \ | 
					
						
							|  |  |  |  |   -d '{ | 
					
						
							|  |  |  |  |     "phone": "13800138000", | 
					
						
							|  |  |  |  |     "scene": "register" | 
					
						
							|  |  |  |  |   }' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 响应示例 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": true, | 
					
						
							|  |  |  |  |   "message": "验证码发送成功", | 
					
						
							|  |  |  |  |   "data": { | 
					
						
							|  |  |  |  |     "message": "验证码已发送到您的手机", | 
					
						
							|  |  |  |  |     "expires_at": "2024-01-01T00:05:00Z" | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 用户注册 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl -X POST http://localhost:8080/api/v1/users/register \ | 
					
						
							|  |  |  |  |   -H "Content-Type: application/json" \ | 
					
						
							|  |  |  |  |   -d '{ | 
					
						
							|  |  |  |  |     "phone": "13800138000", | 
					
						
							|  |  |  |  |     "password": "password123", | 
					
						
							|  |  |  |  |     "confirm_password": "password123", | 
					
						
							|  |  |  |  |     "code": "123456" | 
					
						
							|  |  |  |  |   }' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 响应示例 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": true, | 
					
						
							|  |  |  |  |   "message": "用户注册成功", | 
					
						
							|  |  |  |  |   "data": { | 
					
						
							|  |  |  |  |     "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |     "phone": "13800138000", | 
					
						
							|  |  |  |  |     "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |     "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 密码登录 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl -X POST http://localhost:8080/api/v1/users/login-password \ | 
					
						
							|  |  |  |  |   -H "Content-Type: application/json" \ | 
					
						
							|  |  |  |  |   -d '{ | 
					
						
							|  |  |  |  |     "phone": "13800138000", | 
					
						
							|  |  |  |  |     "password": "password123" | 
					
						
							|  |  |  |  |   }' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 响应示例 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": true, | 
					
						
							|  |  |  |  |   "message": "登录成功", | 
					
						
							|  |  |  |  |   "data": { | 
					
						
							|  |  |  |  |     "user": { | 
					
						
							|  |  |  |  |       "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |       "phone": "13800138000", | 
					
						
							|  |  |  |  |       "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |       "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", | 
					
						
							|  |  |  |  |     "token_type": "Bearer", | 
					
						
							|  |  |  |  |     "expires_in": 86400, | 
					
						
							|  |  |  |  |     "login_method": "password" | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 短信验证码登录 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl -X POST http://localhost:8080/api/v1/users/login-sms \ | 
					
						
							|  |  |  |  |   -H "Content-Type: application/json" \ | 
					
						
							|  |  |  |  |   -d '{ | 
					
						
							|  |  |  |  |     "phone": "13800138000", | 
					
						
							|  |  |  |  |     "code": "123456" | 
					
						
							|  |  |  |  |   }' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 响应示例同密码登录,login_method为"sms" | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 获取当前用户信息 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl -X GET http://localhost:8080/api/v1/users/me \ | 
					
						
							|  |  |  |  |   -H "Authorization: Bearer <your-jwt-token>" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 响应示例 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": true, | 
					
						
							|  |  |  |  |   "message": "获取用户信息成功", | 
					
						
							|  |  |  |  |   "data": { | 
					
						
							|  |  |  |  |     "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |     "phone": "13800138000", | 
					
						
							|  |  |  |  |     "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |     "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 修改密码 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl -X PUT http://localhost:8080/api/v1/users/me/password \ | 
					
						
							|  |  |  |  |   -H "Authorization: Bearer <your-jwt-token>" \ | 
					
						
							|  |  |  |  |   -H "Content-Type: application/json" \ | 
					
						
							|  |  |  |  |   -d '{ | 
					
						
							|  |  |  |  |     "old_password": "oldpassword123", | 
					
						
							|  |  |  |  |     "new_password": "newpassword123", | 
					
						
							|  |  |  |  |     "confirm_new_password": "newpassword123", | 
					
						
							|  |  |  |  |     "code": "123456" | 
					
						
							|  |  |  |  |   }' | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 响应示例 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": true, | 
					
						
							|  |  |  |  |   "message": "密码修改成功", | 
					
						
							|  |  |  |  |   "data": null, | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 错误响应示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | # 参数验证失败 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": false, | 
					
						
							|  |  |  |  |   "message": "请求参数验证失败", | 
					
						
							|  |  |  |  |   "errors": { | 
					
						
							|  |  |  |  |     "phone": ["手机号 长度必须为 11 位"], | 
					
						
							|  |  |  |  |     "password": ["密码 长度不能少于 6 位"] | 
					
						
							|  |  |  |  |   }, | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 业务逻辑错误 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": false, | 
					
						
							|  |  |  |  |   "message": "手机号已被注册", | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 认证失败 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |   "success": false, | 
					
						
							|  |  |  |  |   "message": "用户未登录或登录已过期", | 
					
						
							|  |  |  |  |   "request_id": "req_123456789", | 
					
						
							|  |  |  |  |   "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 🔄 响应格式示例 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 成功响应 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | // 用户注册成功 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": true, | 
					
						
							|  |  |  |  |     "message": "用户注册成功", | 
					
						
							|  |  |  |  |     "data": { | 
					
						
							|  |  |  |  |         "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |         "phone": "13800138000", | 
					
						
							|  |  |  |  |         "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |         "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 用户登录成功 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": true, | 
					
						
							|  |  |  |  |     "message": "登录成功", | 
					
						
							|  |  |  |  |     "data": { | 
					
						
							|  |  |  |  |         "user": { | 
					
						
							|  |  |  |  |             "id": "123e4567-e89b-12d3-a456-426614174000", | 
					
						
							|  |  |  |  |             "phone": "13800138000", | 
					
						
							|  |  |  |  |             "created_at": "2024-01-01T00:00:00Z", | 
					
						
							|  |  |  |  |             "updated_at": "2024-01-01T00:00:00Z" | 
					
						
							|  |  |  |  |         }, | 
					
						
							|  |  |  |  |         "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", | 
					
						
							|  |  |  |  |         "token_type": "Bearer", | 
					
						
							|  |  |  |  |         "expires_in": 86400, | 
					
						
							|  |  |  |  |         "login_method": "password" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 发送验证码成功 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": true, | 
					
						
							|  |  |  |  |     "message": "验证码发送成功", | 
					
						
							|  |  |  |  |     "data": { | 
					
						
							|  |  |  |  |         "message": "验证码已发送", | 
					
						
							|  |  |  |  |         "expires_at": "2024-01-01T00:05:00Z" | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 错误响应 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```json | 
					
						
							|  |  |  |  | // 参数验证失败 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "请求参数验证失败", | 
					
						
							|  |  |  |  |     "errors": { | 
					
						
							|  |  |  |  |         "phone": ["手机号 长度必须为 11 位"], | 
					
						
							|  |  |  |  |         "password": ["密码 长度不能少于 6 位"], | 
					
						
							|  |  |  |  |         "code": ["验证码 长度必须为 6 位"] | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 业务逻辑错误 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "手机号已被注册", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 认证失败 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "用户未登录或登录已过期", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 验证码错误 | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     "success": false, | 
					
						
							|  |  |  |  |     "message": "验证码错误或已过期", | 
					
						
							|  |  |  |  |     "request_id": "req_123456789", | 
					
						
							|  |  |  |  |     "timestamp": 1704067200 | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | --- | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 遵循以上规范,可以确保 API 开发的一致性、可维护性和扩展性。 | 
					
						
							| 
									
										
										
										
											2025-07-11 21:05:58 +08:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | # TYAPI Server 企业级高级特性完整集成指南 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🚀 **高级特性完整解决方案实施完成** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 本项目现已成功集成所有企业级高级特性,提供完整的可观测性、弹性恢复和分布式事务能力。所有组件均已通过编译验证和容器集成。 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📊 **已完整集成的高级特性** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 1. **🔍 分布式链路追踪 (Distributed Tracing)** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **技术栈**: OpenTelemetry + OTLP 导出器   | 
					
						
							|  |  |  |  | **支持后端**: Jaeger、Zipkin、Tempo、任何 OTLP 兼容系统   | 
					
						
							|  |  |  |  | **状态**: ✅ **完全集成** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```yaml | 
					
						
							|  |  |  |  | # 配置示例 (config.yaml) | 
					
						
							|  |  |  |  | monitoring: | 
					
						
							|  |  |  |  |     tracing_enabled: true | 
					
						
							|  |  |  |  |     tracing_endpoint: "http://localhost:4317" # OTLP gRPC endpoint | 
					
						
							|  |  |  |  |     sample_rate: 0.1 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **核心特性**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   ✅ HTTP 请求自动追踪中间件 | 
					
						
							|  |  |  |  | -   ✅ 数据库操作追踪 | 
					
						
							|  |  |  |  | -   ✅ 缓存操作追踪 | 
					
						
							|  |  |  |  | -   ✅ 自定义业务操作追踪 | 
					
						
							|  |  |  |  | -   ✅ TraceID/SpanID 自动传播 | 
					
						
							|  |  |  |  | -   ✅ 生产级批处理导出 | 
					
						
							|  |  |  |  | -   ✅ 容器生命周期管理 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **使用示例**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 自动HTTP追踪(已在所有路由启用) | 
					
						
							|  |  |  |  | // 每个HTTP请求都会创建完整的追踪链路 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 自定义业务操作追踪 | 
					
						
							|  |  |  |  | ctx, span := tracer.StartSpan(ctx, "business.user_registration") | 
					
						
							|  |  |  |  | defer span.End() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 数据库操作追踪 | 
					
						
							|  |  |  |  | ctx, span := tracer.StartDBSpan(ctx, "SELECT", "users", "WHERE phone = ?") | 
					
						
							|  |  |  |  | defer span.End() | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 缓存操作追踪 | 
					
						
							|  |  |  |  | ctx, span := tracer.StartCacheSpan(ctx, "GET", "user:cache:123") | 
					
						
							|  |  |  |  | defer span.End() | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 2. **📈 指标监控 (Metrics Collection)** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **技术栈**: Prometheus + 自定义业务指标   | 
					
						
							|  |  |  |  | **导出端点**: `/metrics` (Prometheus 格式)   | 
					
						
							|  |  |  |  | **状态**: ✅ **完全集成** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **自动收集指标**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | # HTTP请求指标 | 
					
						
							|  |  |  |  | http_requests_total{method="GET",path="/api/v1/users",status="200"} 1523 | 
					
						
							|  |  |  |  | http_request_duration_seconds{method="GET",path="/api/v1/users"} 0.045 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 业务指标 | 
					
						
							|  |  |  |  | business_user_created_total{source="register"} 245 | 
					
						
							|  |  |  |  | business_user_login_total{platform="web",status="success"} 1892 | 
					
						
							|  |  |  |  | business_sms_sent_total{type="verification",provider="aliyun"} 456 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | # 系统指标 | 
					
						
							|  |  |  |  | active_users_total 1024 | 
					
						
							|  |  |  |  | database_connections_active 12 | 
					
						
							|  |  |  |  | cache_operations_total{operation="get",result="hit"} 8745 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **自定义指标注册**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 注册自定义计数器 | 
					
						
							|  |  |  |  | metrics.RegisterCounter("custom_events_total", "Custom events counter", []string{"event_type", "source"}) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 记录指标 | 
					
						
							|  |  |  |  | metrics.IncrementCounter("custom_events_total", map[string]string{ | 
					
						
							|  |  |  |  |     "event_type": "user_action", | 
					
						
							|  |  |  |  |     "source": "web", | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 3. **🛡️ 弹性恢复 (Resilience)** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 3.1 **熔断器 (Circuit Breaker)** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **状态**: ✅ **完全集成** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 使用熔断器保护服务调用 | 
					
						
							|  |  |  |  | err := circuitBreaker.Execute("user-service", func() error { | 
					
						
							|  |  |  |  |     return userService.GetUserByID(ctx, userID) | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 批量执行保护 | 
					
						
							|  |  |  |  | err := circuitBreaker.ExecuteBatch("batch-operation", []func() error{ | 
					
						
							|  |  |  |  |     func() error { return service1.Call() }, | 
					
						
							|  |  |  |  |     func() error { return service2.Call() }, | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **特性**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   ✅ 故障阈值自动检测 | 
					
						
							|  |  |  |  | -   ✅ 半开状态自动恢复 | 
					
						
							|  |  |  |  | -   ✅ 实时状态监控 | 
					
						
							|  |  |  |  | -   ✅ 多种失败策略 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | #### 3.2 **重试机制 (Retry)** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **状态**: ✅ **完全集成** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 快速重试(适用于网络抖动) | 
					
						
							|  |  |  |  | err := retryer.ExecuteWithQuickRetry(ctx, "api-call", func() error { | 
					
						
							|  |  |  |  |     return httpClient.Call() | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 标准重试(适用于业务操作) | 
					
						
							|  |  |  |  | err := retryer.ExecuteWithStandardRetry(ctx, "db-operation", func() error { | 
					
						
							|  |  |  |  |     return db.Save(data) | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 耐心重试(适用于最终一致性) | 
					
						
							|  |  |  |  | err := retryer.ExecuteWithPatientRetry(ctx, "sync-operation", func() error { | 
					
						
							|  |  |  |  |     return syncService.Sync() | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 4. **🔄 分布式事务 (Saga Pattern)** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **状态**: ✅ **完全集成** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 创建分布式事务 | 
					
						
							|  |  |  |  | saga := sagaManager.CreateSaga("user-registration-001", "用户注册流程") | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 添加事务步骤 | 
					
						
							|  |  |  |  | saga.AddStep("create-user", | 
					
						
							|  |  |  |  |     // 正向操作 | 
					
						
							|  |  |  |  |     func(ctx context.Context, data interface{}) error { | 
					
						
							|  |  |  |  |         return userService.CreateUser(ctx, data) | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     // 补偿操作 | 
					
						
							|  |  |  |  |     func(ctx context.Context, data interface{}) error { | 
					
						
							|  |  |  |  |         return userService.DeleteUser(ctx, data) | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | saga.AddStep("send-welcome-email", | 
					
						
							|  |  |  |  |     func(ctx context.Context, data interface{}) error { | 
					
						
							|  |  |  |  |         return emailService.SendWelcome(ctx, data) | 
					
						
							|  |  |  |  |     }, | 
					
						
							|  |  |  |  |     func(ctx context.Context, data interface{}) error { | 
					
						
							|  |  |  |  |         return emailService.SendCancellation(ctx, data) | 
					
						
							|  |  |  |  |     }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 执行事务 | 
					
						
							|  |  |  |  | err := saga.Execute(ctx, userData) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **支持特性**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   ✅ 自动补偿机制 | 
					
						
							|  |  |  |  | -   ✅ 步骤重试策略 | 
					
						
							|  |  |  |  | -   ✅ 事务状态跟踪 | 
					
						
							|  |  |  |  | -   ✅ 并发控制 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### 5. **🪝 事件钩子系统 (Hook System)** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **状态**: ✅ **完全集成** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```go | 
					
						
							|  |  |  |  | // 注册业务事件钩子 | 
					
						
							|  |  |  |  | hookSystem.OnUserCreated("metrics-collector", hooks.PriorityHigh, func(ctx context.Context, user interface{}) error { | 
					
						
							|  |  |  |  |     return businessMetrics.RecordUserCreated("register") | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | hookSystem.OnUserCreated("welcome-email", hooks.PriorityNormal, func(ctx context.Context, user interface{}) error { | 
					
						
							|  |  |  |  |     return emailService.SendWelcome(ctx, user) | 
					
						
							|  |  |  |  | }) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // 触发事件(在业务代码中) | 
					
						
							|  |  |  |  | results, err := hookSystem.TriggerUserCreated(ctx, newUser) | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | **钩子类型**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   ✅ 同步钩子(阻塞执行) | 
					
						
							|  |  |  |  | -   ✅ 异步钩子(后台执行) | 
					
						
							|  |  |  |  | -   ✅ 优先级控制 | 
					
						
							|  |  |  |  | -   ✅ 超时保护 | 
					
						
							|  |  |  |  | -   ✅ 错误策略(继续/停止/收集) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🏗️ **架构集成图** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | ┌─────────────────────────────────────────────────────────────┐ | 
					
						
							|  |  |  |  | │                      HTTP 请求层                             │ | 
					
						
							|  |  |  |  | ├─────────────────────────────────────────────────────────────┤ | 
					
						
							|  |  |  |  | │  追踪中间件 → 指标中间件 → 限流中间件 → 认证中间件            │ | 
					
						
							|  |  |  |  | ├─────────────────────────────────────────────────────────────┤ | 
					
						
							|  |  |  |  | │                    业务处理层                                │ | 
					
						
							|  |  |  |  | │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │ | 
					
						
							|  |  |  |  | │  │   Handler   │  │   Service   │  │  Repository │         │ | 
					
						
							|  |  |  |  | │  │   + 钩子    │  │  + 重试     │  │  + 熔断器   │         │ | 
					
						
							|  |  |  |  | │  └─────────────┘  └─────────────┘  └─────────────┘         │ | 
					
						
							|  |  |  |  | ├─────────────────────────────────────────────────────────────┤ | 
					
						
							|  |  |  |  | │                    基础设施层                                │ | 
					
						
							|  |  |  |  | │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐         │ | 
					
						
							|  |  |  |  | │  │ 链路追踪    │  │ 指标收集    │  │ 分布式事务  │         │ | 
					
						
							|  |  |  |  | │  │ (OpenTel)   │  │(Prometheus) │  │   (Saga)    │         │ | 
					
						
							|  |  |  |  | │  └─────────────┘  └─────────────┘  └─────────────┘         │ | 
					
						
							|  |  |  |  | └─────────────────────────────────────────────────────────────┘ | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🛠️ **使用指南** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **启动验证** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 1. **编译验证**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | go build ./cmd/api | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 2. **启动应用**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | ./api | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 3. **检查指标端点**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl http://localhost:8080/metrics | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 4. **检查健康状态**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```bash | 
					
						
							|  |  |  |  | curl http://localhost:8080/health | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **配置示例** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```yaml | 
					
						
							|  |  |  |  | # config.yaml 完整高级特性配置 | 
					
						
							|  |  |  |  | app: | 
					
						
							|  |  |  |  |     name: "tyapi-server" | 
					
						
							|  |  |  |  |     version: "1.0.0" | 
					
						
							|  |  |  |  |     env: "production" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | monitoring: | 
					
						
							|  |  |  |  |     # 链路追踪配置 | 
					
						
							|  |  |  |  |     tracing_enabled: true | 
					
						
							|  |  |  |  |     tracing_endpoint: "http://jaeger:4317" | 
					
						
							|  |  |  |  |     sample_rate: 0.1 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # 指标收集配置 | 
					
						
							|  |  |  |  |     metrics_enabled: true | 
					
						
							|  |  |  |  |     metrics_endpoint: "/metrics" | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | resilience: | 
					
						
							|  |  |  |  |     # 熔断器配置 | 
					
						
							|  |  |  |  |     circuit_breaker_enabled: true | 
					
						
							|  |  |  |  |     failure_threshold: 5 | 
					
						
							|  |  |  |  |     timeout: 30s | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     # 重试配置 | 
					
						
							|  |  |  |  |     retry_enabled: true | 
					
						
							|  |  |  |  |     max_retries: 3 | 
					
						
							|  |  |  |  |     retry_delay: 100ms | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | saga: | 
					
						
							|  |  |  |  |     # 分布式事务配置 | 
					
						
							|  |  |  |  |     default_timeout: 30s | 
					
						
							|  |  |  |  |     max_retries: 3 | 
					
						
							|  |  |  |  |     enable_persistence: false | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | hooks: | 
					
						
							|  |  |  |  |     # 钩子系统配置 | 
					
						
							|  |  |  |  |     default_timeout: 30s | 
					
						
							|  |  |  |  |     track_duration: true | 
					
						
							|  |  |  |  |     error_strategy: "continue" | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 📋 **监控仪表板** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **推荐监控栈** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 1. **链路追踪**: Jaeger UI | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - 地址: `http://localhost:16686` | 
					
						
							|  |  |  |  |     - 查看完整请求链路 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 2. **指标监控**: Prometheus + Grafana | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - Prometheus: `http://localhost:9090` | 
					
						
							|  |  |  |  |     - Grafana: `http://localhost:3000` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 3. **应用指标**: 内置指标端点 | 
					
						
							|  |  |  |  |     - 地址: `http://localhost:8080/metrics` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **关键监控指标** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ```yaml | 
					
						
							|  |  |  |  | # 告警规则建议 | 
					
						
							|  |  |  |  | groups: | 
					
						
							|  |  |  |  |     - name: tyapi-server | 
					
						
							|  |  |  |  |       rules: | 
					
						
							|  |  |  |  |           - alert: HighErrorRate | 
					
						
							|  |  |  |  |             expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           - alert: CircuitBreakerOpen | 
					
						
							|  |  |  |  |             expr: circuit_breaker_state{state="open"} > 0 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           - alert: SagaFailure | 
					
						
							|  |  |  |  |             expr: rate(saga_failed_total[5m]) > 0.05 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |           - alert: HighLatency | 
					
						
							|  |  |  |  |             expr: histogram_quantile(0.95, http_request_duration_seconds) > 1 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🔧 **性能优化建议** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **生产环境配置** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 1. **追踪采样率**: 建议设置为 0.01-0.1 (1%-10%) | 
					
						
							|  |  |  |  | 2. **指标收集**: 启用所有核心指标,按需启用业务指标 | 
					
						
							|  |  |  |  | 3. **熔断器阈值**: 根据服务 SLA 调整失败阈值 | 
					
						
							|  |  |  |  | 4. **钩子超时**: 设置合理的钩子执行超时时间 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **扩展性考虑** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 1. **水平扩展**: 所有组件都支持多实例部署 | 
					
						
							|  |  |  |  | 2. **状态无关**: 追踪和指标数据通过外部系统存储 | 
					
						
							|  |  |  |  | 3. **配置热更新**: 支持运行时配置调整 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🎯 **最佳实践** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **链路追踪** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   在关键业务操作中主动创建 Span | 
					
						
							|  |  |  |  | -   使用有意义的操作名称 | 
					
						
							|  |  |  |  | -   添加重要的标签和属性 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **指标收集** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   合理设置指标标签,避免高基数 | 
					
						
							|  |  |  |  | -   定期清理不再使用的指标 | 
					
						
							|  |  |  |  | -   使用直方图记录耗时分布 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **弹性设计** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   在外部服务调用时使用熔断器 | 
					
						
							|  |  |  |  | -   对瞬时失败使用重试机制 | 
					
						
							|  |  |  |  | -   设计优雅降级策略 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **事件钩子** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   保持钩子函数简单快速 | 
					
						
							|  |  |  |  | -   使用异步钩子处理耗时操作 | 
					
						
							|  |  |  |  | -   合理设置钩子优先级 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🔍 **故障排查** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ### **常见问题** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 1. **追踪数据丢失** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - 检查 OTLP 端点连接性 | 
					
						
							|  |  |  |  |     - 确认采样率配置 | 
					
						
							|  |  |  |  |     - 查看应用日志中的追踪错误 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 2. **指标不更新** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     - 验证 Prometheus 抓取配置 | 
					
						
							|  |  |  |  |     - 检查指标端点可访问性 | 
					
						
							|  |  |  |  |     - 确认指标注册成功 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 3. **熔断器异常触发** | 
					
						
							|  |  |  |  |     - 检查失败阈值设置 | 
					
						
							|  |  |  |  |     - 分析下游服务健康状态 | 
					
						
							|  |  |  |  |     - 调整超时时间 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🏆 **集成完成状态** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | | 特性模块   | 实现状态 | 容器集成 | 中间件        | 配置支持 | 文档完整度 | | 
					
						
							|  |  |  |  | | ---------- | -------- | -------- | ------------- | -------- | ---------- | | 
					
						
							|  |  |  |  | | 链路追踪   | ✅ 100%  | ✅ 完成  | ✅ 已集成     | ✅ 完整  | ✅ 完整    | | 
					
						
							|  |  |  |  | | 指标监控   | ✅ 100%  | ✅ 完成  | ✅ 已集成     | ✅ 完整  | ✅ 完整    | | 
					
						
							|  |  |  |  | | 熔断器     | ✅ 100%  | ✅ 完成  | ⚠️ 手动集成   | ✅ 完整  | ✅ 完整    | | 
					
						
							|  |  |  |  | | 重试机制   | ✅ 100%  | ✅ 完成  | ⚠️ 手动集成   | ✅ 完整  | ✅ 完整    | | 
					
						
							|  |  |  |  | | 分布式事务 | ✅ 100%  | ✅ 完成  | ⚠️ 手动集成   | ✅ 完整  | ✅ 完整    | | 
					
						
							|  |  |  |  | | 钩子系统   | ✅ 100%  | ✅ 完成  | ⚠️ 应用级集成 | ✅ 完整  | ✅ 完整    | | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ## 🎉 **总结** | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | TYAPI Server 现已完成所有企业级高级特性的完整集成: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ✅ **已完成的核心能力**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   分布式链路追踪 (OpenTelemetry + OTLP) | 
					
						
							|  |  |  |  | -   全方位指标监控 (Prometheus + 业务指标) | 
					
						
							|  |  |  |  | -   多层次弹性恢复 (熔断器 + 重试机制) | 
					
						
							|  |  |  |  | -   分布式事务管理 (Saga 模式) | 
					
						
							|  |  |  |  | -   灵活事件钩子系统 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ✅ **生产就绪特性**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   完整的容器依赖注入 | 
					
						
							|  |  |  |  | -   自动化中间件集成 | 
					
						
							|  |  |  |  | -   优雅的生命周期管理 | 
					
						
							|  |  |  |  | -   完善的配置系统 | 
					
						
							|  |  |  |  | -   详细的监控指标 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ✅ **开发体验**: | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | -   编译零错误 | 
					
						
							|  |  |  |  | -   热插拔组件设计 | 
					
						
							|  |  |  |  | -   丰富的使用示例 | 
					
						
							|  |  |  |  | -   完整的故障排查指南 | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | 现在您的 TYAPI Server 已经具备了企业级产品的所有核心监控和弹性能力!🚀 |