feat: 完成B端认证系统和商户管理模块测试补全
主要变更: - 新增B端认证系统(后台+H5):登录、登出、Token刷新、密码修改 - 完善商户管理和商户账号管理功能 - 补全单元测试(ShopService: 72.5%, ShopAccountService: 79.8%) - 新增集成测试(商户管理+商户账号管理) - 归档OpenSpec提案(add-shop-account-management, implement-b-end-auth-system) - 完善文档(使用指南、API文档、认证架构说明) 测试统计: - 13个测试套件,37个测试用例,100%通过率 - 平均覆盖率76.2%,达标 OpenSpec验证:通过(strict模式)
This commit is contained in:
@@ -24,11 +24,82 @@ func NewGenerator(title, version string) *Generator {
|
||||
Version: version,
|
||||
},
|
||||
}
|
||||
return &Generator{Reflector: &reflector}
|
||||
|
||||
g := &Generator{Reflector: &reflector}
|
||||
g.addBearerAuth()
|
||||
return g
|
||||
}
|
||||
|
||||
// addBearerAuth 添加 Bearer Token 认证定义
|
||||
func (g *Generator) addBearerAuth() {
|
||||
bearerFormat := "JWT"
|
||||
g.Reflector.Spec.ComponentsEns().SecuritySchemesEns().WithMapOfSecuritySchemeOrRefValuesItem(
|
||||
"BearerAuth",
|
||||
openapi3.SecuritySchemeOrRef{
|
||||
SecurityScheme: &openapi3.SecurityScheme{
|
||||
HTTPSecurityScheme: &openapi3.HTTPSecurityScheme{
|
||||
Scheme: "bearer",
|
||||
BearerFormat: &bearerFormat,
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
g.addErrorResponseSchema()
|
||||
}
|
||||
|
||||
// addErrorResponseSchema 添加错误响应 Schema 定义
|
||||
func (g *Generator) addErrorResponseSchema() {
|
||||
objectType := openapi3.SchemaType("object")
|
||||
integerType := openapi3.SchemaType("integer")
|
||||
stringType := openapi3.SchemaType("string")
|
||||
dateTimeFormat := "date-time"
|
||||
|
||||
errorSchema := openapi3.SchemaOrRef{
|
||||
Schema: &openapi3.Schema{
|
||||
Type: &objectType,
|
||||
Properties: map[string]openapi3.SchemaOrRef{
|
||||
"code": {
|
||||
Schema: &openapi3.Schema{
|
||||
Type: &integerType,
|
||||
Description: ptrString("错误码"),
|
||||
},
|
||||
},
|
||||
"message": {
|
||||
Schema: &openapi3.Schema{
|
||||
Type: &stringType,
|
||||
Description: ptrString("错误消息"),
|
||||
},
|
||||
},
|
||||
"timestamp": {
|
||||
Schema: &openapi3.Schema{
|
||||
Type: &stringType,
|
||||
Format: &dateTimeFormat,
|
||||
Description: ptrString("时间戳"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"code", "message", "timestamp"},
|
||||
},
|
||||
}
|
||||
|
||||
g.Reflector.Spec.ComponentsEns().SchemasEns().WithMapOfSchemaOrRefValuesItem("ErrorResponse", errorSchema)
|
||||
}
|
||||
|
||||
// ptrString 返回字符串指针
|
||||
func ptrString(s string) *string {
|
||||
return &s
|
||||
}
|
||||
|
||||
// AddOperation 向 OpenAPI 规范中添加一个操作
|
||||
func (g *Generator) AddOperation(method, path, summary string, input interface{}, output interface{}, tags ...string) {
|
||||
// 参数:
|
||||
// - method: HTTP 方法(GET, POST, PUT, DELETE 等)
|
||||
// - path: API 路径
|
||||
// - summary: 操作摘要
|
||||
// - input: 请求参数结构体(可为 nil)
|
||||
// - output: 响应结构体(可为 nil)
|
||||
// - tags: 标签列表
|
||||
// - requiresAuth: 是否需要认证
|
||||
func (g *Generator) AddOperation(method, path, summary string, input interface{}, output interface{}, requiresAuth bool, tags ...string) {
|
||||
op := openapi3.Operation{
|
||||
Summary: &summary,
|
||||
Tags: tags,
|
||||
@@ -49,12 +120,104 @@ func (g *Generator) AddOperation(method, path, summary string, input interface{}
|
||||
}
|
||||
}
|
||||
|
||||
// 添加认证要求
|
||||
if requiresAuth {
|
||||
g.addSecurityRequirement(&op)
|
||||
}
|
||||
|
||||
// 添加标准错误响应
|
||||
g.addStandardErrorResponses(&op, requiresAuth)
|
||||
|
||||
// 将操作添加到规范中
|
||||
if err := g.Reflector.Spec.AddOperation(method, path, op); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// addSecurityRequirement 为操作添加认证要求
|
||||
func (g *Generator) addSecurityRequirement(op *openapi3.Operation) {
|
||||
op.Security = []map[string][]string{
|
||||
{"BearerAuth": {}},
|
||||
}
|
||||
}
|
||||
|
||||
// addStandardErrorResponses 添加标准错误响应
|
||||
func (g *Generator) addStandardErrorResponses(op *openapi3.Operation, requiresAuth bool) {
|
||||
if op.Responses.MapOfResponseOrRefValues == nil {
|
||||
op.Responses.MapOfResponseOrRefValues = make(map[string]openapi3.ResponseOrRef)
|
||||
}
|
||||
|
||||
// 400 Bad Request - 所有端点都可能返回
|
||||
desc400 := "请求参数错误"
|
||||
op.Responses.MapOfResponseOrRefValues["400"] = openapi3.ResponseOrRef{
|
||||
Response: &openapi3.Response{
|
||||
Description: desc400,
|
||||
Content: map[string]openapi3.MediaType{
|
||||
"application/json": {
|
||||
Schema: &openapi3.SchemaOrRef{
|
||||
SchemaReference: &openapi3.SchemaReference{
|
||||
Ref: "#/components/schemas/ErrorResponse",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 401 Unauthorized - 仅认证端点返回
|
||||
if requiresAuth {
|
||||
desc401 := "未认证或认证已过期"
|
||||
op.Responses.MapOfResponseOrRefValues["401"] = openapi3.ResponseOrRef{
|
||||
Response: &openapi3.Response{
|
||||
Description: desc401,
|
||||
Content: map[string]openapi3.MediaType{
|
||||
"application/json": {
|
||||
Schema: &openapi3.SchemaOrRef{
|
||||
SchemaReference: &openapi3.SchemaReference{
|
||||
Ref: "#/components/schemas/ErrorResponse",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 403 Forbidden - 仅认证端点返回
|
||||
desc403 := "无权访问"
|
||||
op.Responses.MapOfResponseOrRefValues["403"] = openapi3.ResponseOrRef{
|
||||
Response: &openapi3.Response{
|
||||
Description: desc403,
|
||||
Content: map[string]openapi3.MediaType{
|
||||
"application/json": {
|
||||
Schema: &openapi3.SchemaOrRef{
|
||||
SchemaReference: &openapi3.SchemaReference{
|
||||
Ref: "#/components/schemas/ErrorResponse",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// 500 Internal Server Error - 所有端点都可能返回
|
||||
desc500 := "服务器内部错误"
|
||||
op.Responses.MapOfResponseOrRefValues["500"] = openapi3.ResponseOrRef{
|
||||
Response: &openapi3.Response{
|
||||
Description: desc500,
|
||||
Content: map[string]openapi3.MediaType{
|
||||
"application/json": {
|
||||
Schema: &openapi3.SchemaOrRef{
|
||||
SchemaReference: &openapi3.SchemaReference{
|
||||
Ref: "#/components/schemas/ErrorResponse",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Save 将规范导出为 YAML 文件
|
||||
func (g *Generator) Save(filename string) error {
|
||||
// 确保目录存在
|
||||
|
||||
Reference in New Issue
Block a user