diff --git a/README.md b/README.md index 67580dc..762dda2 100644 --- a/README.md +++ b/README.md @@ -83,4 +83,23 @@ Description: # 数据库注释使用 1. 使用注释@type(int), 强制设置生成的go struct 属性 类型 -2. 使用注释@index, 强制生成索引赋值函数 \ No newline at end of file +2. 使用注释@index, 强制生成索引赋值函数 + + +# 生成文档 +定义方式 +````protobuf +service Controller { + // 发送通知文档, 不用请求 + rpc Api(ApiRequest)returns(ApiResponse){ + option (http.Post) = "/test"; + // 没有权限 + option (http.Status) = {Code: 401,Response: "TResponse"}; + // test + option (http.Status) = {Code: 402,Response: "TTResponse"}; + // test + option (http.Status) = {Code: 403,Response: "TTTResponse"}; + } +} +message TResponse {} +```` \ No newline at end of file diff --git a/console/commands/swagger.go b/console/commands/swagger.go index 27c3dc6..1061769 100644 --- a/console/commands/swagger.go +++ b/console/commands/swagger.go @@ -147,10 +147,26 @@ func defName(name string) string { return name } +func getUrl(opts map[string][]parser.Option) string { + urlPath := "" + for _, options := range opts { + for _, option := range options { + switch option.Key { + case "http.Get", "http.Put", "http.Post", "http.Patch", "http.Delete": + urlPath = option.Val + } + } + } + return urlPath +} + func rpcToPath(pge string, service parser.ServiceRpc, swagger *openapi.Spec, nowDirProtoc []parser.ProtocFileParser, allProtoc map[string][]parser.ProtocFileParser, serviceOpt map[string]parser.Option) { for _, options := range service.Opt { for _, option := range options { urlPath := option.Val + if urlPath == "" { + urlPath = getUrl(service.Opt) + } if routeGroup, ok := serviceOpt["http.RouteGroup"]; ok { urlPath = "$[" + routeGroup.Val + "]" + urlPath } @@ -158,14 +174,38 @@ func rpcToPath(pge string, service parser.ServiceRpc, swagger *openapi.Spec, now if o, ok := swagger.Paths[urlPath]; ok { path = o } - endpoint := &openapi.Endpoint{} - endpoint.Description = service.Doc + option.Doc - endpoint.Summary = service.Doc + option.Doc - endpoint.Tags = strings.Split(pge, ".") - endpoint.Parameters = messageToParameters(option.Key, service.Param, nowDirProtoc, allProtoc) - endpoint.Responses = map[string]*openapi.Response{ - "200": messageToResponse(service.Return, nowDirProtoc, allProtoc), + switch option.Key { + case "http.Get", "http.Put", "http.Post", "http.Patch", "http.Delete": + endpoint.Description = service.Doc + option.Doc + endpoint.Summary = service.Doc + option.Doc + endpoint.Tags = strings.Split(pge, ".") + endpoint.Parameters = messageToParameters(option.Key, service.Param, nowDirProtoc, allProtoc) + endpoint.Responses = map[string]*openapi.Response{ + "200": messageToResponse(service.Return, nowDirProtoc, allProtoc), + } + case "http.Status": + // 其他状态码的返回结构 + for _, endpoint := range []*openapi.Endpoint{ + path.Get, + path.Post, + path.Put, + path.Patch, + path.Delete, + } { + if endpoint != nil { + code := option.Map["Code"] + resp := option.Map["Response"] + endpoint.Responses[code] = &openapi.Response{ + Description: option.Doc, + Schema: &openapi.Schema{ + Ref: "#/definitions/" + resp, + }, + } + } + } + default: + continue } switch option.Key { diff --git a/parser/protoc.go b/parser/protoc.go index b303454..5745f57 100644 --- a/parser/protoc.go +++ b/parser/protoc.go @@ -23,6 +23,7 @@ type Option struct { Doc string Key string Val string + Map map[string]string wl []*word alias string } @@ -193,7 +194,6 @@ func serverOption(l []*word, offset int) (Option, int) { st, et := GetBrackets(l[offset:], "(", ")") wl := l[offset+st : offset+et+1] offset = offset + et + 1 - val, i := GetFistWord(l[offset:]) var key string var alias string if len(wl) >= 5 { @@ -202,13 +202,39 @@ func serverOption(l []*word, offset int) (Option, int) { for _, w := range wl { key = key + w.Str } + val, i := GetFistWord(l[offset:]) + var opVal string + opMap := make(map[string]string) + if HasPrefix(l[offset+i].Str, "\"") { + opVal = val[1 : len(val)-1] + offset = offset + i + } else { + // option 值是对象 + st, et := GetBrackets(l[offset+i-1:], "{", "}") + nl := l[offset+i-1+st : offset+i-1+et] + // 只支持键值对 + mKey := "" + for _, w := range nl { + switch w.Ty { + case wordT_word: + if mKey == "" { + mKey = w.Str + } else { + opMap[mKey] = strings.Trim(w.Str, "\"") + mKey = "" + } + } + } + offset = offset + i + et + } return Option{ Key: key[1 : len(key)-1], - Val: val[1 : len(val)-1], + Val: opVal, + Map: opMap, wl: wl, alias: alias, - }, offset + i + }, offset } func protoService(l []*word, offset int) (Service, int) { name, i := GetFistWordBehindStr(l[offset:], "service")