feat: OpenAPI 契约对齐与框架优化
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m45s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m45s
主要变更: 1. OpenAPI 文档契约对齐 - 统一错误响应字段名为 msg(非 message) - 规范 envelope 响应结构(code, msg, data, timestamp) - 个人客户路由纳入文档体系(使用 Register 机制) - 新增 BuildDocHandlers() 统一管理 handler 构造 - 确保文档生成的幂等性 2. Service 层错误处理统一 - 全面替换 fmt.Errorf 为 errors.New/Wrap - 统一错误码使用规范 - Handler 层参数校验不泄露底层细节 - 新增错误码验证集成测试 3. 代码质量提升 - 删除未使用的 Task handler 和路由 - 新增代码规范检查脚本(check-service-errors.sh) - 新增注释路径一致性检查(check-comment-paths.sh) - 更新 API 文档生成指南 4. OpenSpec 归档 - 归档 openapi-contract-alignment 变更(63 tasks) - 归档 service-error-unify-core 变更 - 归档 service-error-unify-support 变更 - 归档 code-cleanup-docs-update 变更 - 归档 handler-validation-security 变更 - 同步 delta specs 到主规范文件 影响范围: - pkg/openapi: 新增 handlers.go,优化 generator.go - internal/service/*: 48 个 service 文件错误处理统一 - internal/handler/admin: 优化参数校验错误提示 - internal/routes: 个人客户路由改造,删除 task 路由 - scripts: 新增 3 个代码检查脚本 - docs: 更新 OpenAPI 文档(15750+ 行) - openspec/specs: 同步 3 个主规范文件 破坏性变更:无 向后兼容:是
This commit is contained in:
@@ -1,38 +1,71 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"github.com/break/junhong_cmp_fiber/internal/bootstrap"
|
||||
"github.com/break/junhong_cmp_fiber/internal/middleware"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/bootstrap"
|
||||
apphandler "github.com/break/junhong_cmp_fiber/internal/handler/app"
|
||||
"github.com/break/junhong_cmp_fiber/internal/middleware"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/openapi"
|
||||
)
|
||||
|
||||
// RegisterPersonalCustomerRoutes 注册个人客户路由
|
||||
// 路由挂载在 /api/c/v1 下
|
||||
func RegisterPersonalCustomerRoutes(app *fiber.App, handlers *bootstrap.Handlers, personalAuthMiddleware *middleware.PersonalAuthMiddleware) {
|
||||
// C端路由组 (Customer)
|
||||
customerGroup := app.Group("/api/c/v1")
|
||||
|
||||
func RegisterPersonalCustomerRoutes(router fiber.Router, doc *openapi.Generator, basePath string, handlers *bootstrap.Handlers, personalAuthMiddleware *middleware.PersonalAuthMiddleware) {
|
||||
// 公开路由(不需要认证)
|
||||
publicGroup := customerGroup.Group("")
|
||||
{
|
||||
// 发送验证码
|
||||
publicGroup.Post("/login/send-code", handlers.PersonalCustomer.SendCode)
|
||||
publicGroup := router.Group("")
|
||||
|
||||
// 登录
|
||||
publicGroup.Post("/login", handlers.PersonalCustomer.Login)
|
||||
}
|
||||
// 发送验证码
|
||||
Register(publicGroup, doc, basePath, "POST", "/login/send-code", handlers.PersonalCustomer.SendCode, RouteSpec{
|
||||
Summary: "发送验证码",
|
||||
Description: "向指定手机号发送登录验证码",
|
||||
Tags: []string{"个人客户 - 认证"},
|
||||
Auth: false,
|
||||
Input: &apphandler.SendCodeRequest{},
|
||||
Output: nil,
|
||||
})
|
||||
|
||||
// 登录
|
||||
Register(publicGroup, doc, basePath, "POST", "/login", handlers.PersonalCustomer.Login, RouteSpec{
|
||||
Summary: "手机号登录",
|
||||
Description: "使用手机号和验证码登录",
|
||||
Tags: []string{"个人客户 - 认证"},
|
||||
Auth: false,
|
||||
Input: &apphandler.LoginRequest{},
|
||||
Output: &apphandler.LoginResponse{},
|
||||
})
|
||||
|
||||
// 需要认证的路由
|
||||
authGroup := customerGroup.Group("")
|
||||
authGroup := router.Group("")
|
||||
authGroup.Use(personalAuthMiddleware.Authenticate())
|
||||
{
|
||||
// 绑定微信
|
||||
authGroup.Post("/bind-wechat", handlers.PersonalCustomer.BindWechat)
|
||||
|
||||
// 获取个人资料
|
||||
authGroup.Get("/profile", handlers.PersonalCustomer.GetProfile)
|
||||
// 绑定微信
|
||||
Register(authGroup, doc, basePath, "POST", "/bind-wechat", handlers.PersonalCustomer.BindWechat, RouteSpec{
|
||||
Summary: "绑定微信",
|
||||
Description: "绑定微信账号到当前个人客户",
|
||||
Tags: []string{"个人客户 - 账户"},
|
||||
Auth: true,
|
||||
Input: &apphandler.BindWechatRequest{},
|
||||
Output: nil,
|
||||
})
|
||||
|
||||
// 更新个人资料
|
||||
authGroup.Put("/profile", handlers.PersonalCustomer.UpdateProfile)
|
||||
}
|
||||
// 获取个人资料
|
||||
Register(authGroup, doc, basePath, "GET", "/profile", handlers.PersonalCustomer.GetProfile, RouteSpec{
|
||||
Summary: "获取个人资料",
|
||||
Description: "获取当前登录客户的个人资料",
|
||||
Tags: []string{"个人客户 - 账户"},
|
||||
Auth: true,
|
||||
Input: nil,
|
||||
Output: &apphandler.PersonalCustomerDTO{},
|
||||
})
|
||||
|
||||
// 更新个人资料
|
||||
Register(authGroup, doc, basePath, "PUT", "/profile", handlers.PersonalCustomer.UpdateProfile, RouteSpec{
|
||||
Summary: "更新个人资料",
|
||||
Description: "更新当前登录客户的昵称和头像",
|
||||
Tags: []string{"个人客户 - 账户"},
|
||||
Auth: true,
|
||||
Input: &apphandler.UpdateProfileRequest{},
|
||||
Output: nil,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -22,15 +22,13 @@ func RegisterRoutesWithDoc(app *fiber.App, handlers *bootstrap.Handlers, middlew
|
||||
adminGroup := app.Group("/api/admin")
|
||||
RegisterAdminRoutes(adminGroup, handlers, middlewares, doc, "/api/admin")
|
||||
|
||||
// 任务相关路由 (归属于 Admin 域)
|
||||
registerTaskRoutes(adminGroup, doc, "/api/admin")
|
||||
|
||||
// 3. H5 域 (挂载在 /api/h5)
|
||||
h5Group := app.Group("/api/h5")
|
||||
RegisterH5Routes(h5Group, handlers, middlewares, doc, "/api/h5")
|
||||
|
||||
// 4. 个人客户路由 (挂载在 /api/c/v1)
|
||||
RegisterPersonalCustomerRoutes(app, handlers, middlewares.PersonalAuth)
|
||||
personalGroup := app.Group("/api/c/v1")
|
||||
RegisterPersonalCustomerRoutes(personalGroup, doc, "/api/c/v1", handlers, middlewares.PersonalAuth)
|
||||
|
||||
// 5. 支付回调路由 (挂载在 /api/callback,无需认证)
|
||||
if handlers.PaymentCallback != nil {
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"github.com/gofiber/fiber/v2"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/openapi"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/response"
|
||||
)
|
||||
|
||||
type TaskStatusResponse struct {
|
||||
ID string `json:"id" description:"任务ID"`
|
||||
Status string `json:"status" description:"任务状态 (pending:待处理, running:执行中, completed:已完成, failed:失败)"`
|
||||
}
|
||||
|
||||
func registerTaskRoutes(api fiber.Router, doc *openapi.Generator, basePath string) {
|
||||
tasks := api.Group("/tasks")
|
||||
groupPath := basePath + "/tasks"
|
||||
|
||||
Register(tasks, doc, groupPath, "GET", "/:id", func(c *fiber.Ctx) error {
|
||||
taskID := c.Params("id")
|
||||
return response.Success(c, fiber.Map{
|
||||
"id": taskID,
|
||||
"status": "pending",
|
||||
})
|
||||
}, RouteSpec{
|
||||
Summary: "查询任务状态",
|
||||
Tags: []string{"任务管理"},
|
||||
Input: new(dto.IDReq),
|
||||
Output: new(TaskStatusResponse),
|
||||
Auth: true,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user