package service import ( "bufio" "fmt" "os" "path/filepath" "regexp" "strings" ) // SwaggerInfo Swagger注释信息 type SwaggerInfo struct { Summary string Description string Tags string Router string Method string } // SwaggerParser Swagger注释解析器 type SwaggerParser struct { swaggerMap map[string]SwaggerInfo } // NewSwaggerParser 创建Swagger解析器 func NewSwaggerParser() *SwaggerParser { parser := &SwaggerParser{ swaggerMap: make(map[string]SwaggerInfo), } fmt.Println("🔧 SwaggerParser创建成功") return parser } // ParseControllerDirectory 解析Controller目录下的所有文件 func (sp *SwaggerParser) ParseControllerDirectory(dir string) error { fmt.Printf("🔍 开始解析Controller目录: %s\n", dir) fileCount := 0 err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { if err != nil { fmt.Printf("❌ 访问文件失败: %s, 错误: %v\n", path, err) return err } if !info.IsDir() && strings.HasSuffix(path, ".go") { fmt.Printf("📄 解析文件: %s\n", path) fileCount++ return sp.parseControllerFile(path) } return nil }) fmt.Printf("📊 解析完成,共处理 %d 个Go文件\n", fileCount) fmt.Printf("📋 解析到的Swagger信息数量: %d\n", len(sp.swaggerMap)) return err } // parseControllerFile 解析单个Controller文件 func (sp *SwaggerParser) parseControllerFile(filePath string) error { file, err := os.Open(filePath) if err != nil { return err } defer file.Close() scanner := bufio.NewScanner(file) var currentComment []string for scanner.Scan() { line := scanner.Text() // 检查是否是注释行 if strings.HasPrefix(strings.TrimSpace(line), "//") { currentComment = append(currentComment, line) } else { // 如果不是注释行,处理之前收集的注释 if len(currentComment) > 0 { swaggerInfo := sp.extractSwaggerInfo(currentComment) if swaggerInfo.Router != "" { // 使用Router路径作为key key := fmt.Sprintf("%s %s", swaggerInfo.Method, swaggerInfo.Router) sp.swaggerMap[key] = swaggerInfo } currentComment = nil } } } return scanner.Err() } // extractSwaggerInfo 从注释中提取Swagger信息 func (sp *SwaggerParser) extractSwaggerInfo(comments []string) SwaggerInfo { info := SwaggerInfo{} for _, comment := range comments { comment = strings.TrimSpace(comment) // 提取@Summary if strings.HasPrefix(comment, "// @Summary") { info.Summary = strings.TrimSpace(strings.TrimPrefix(comment, "// @Summary")) } // 提取@Description if strings.HasPrefix(comment, "// @Description") { info.Description = strings.TrimSpace(strings.TrimPrefix(comment, "// @Description")) } // 提取@Tags if strings.HasPrefix(comment, "// @Tags") { info.Tags = strings.TrimSpace(strings.TrimPrefix(comment, "// @Tags")) } // 提取@Router if strings.HasPrefix(comment, "// @Router") { routerLine := strings.TrimSpace(strings.TrimPrefix(comment, "// @Router")) // 解析格式:/path [method] parts := strings.Fields(routerLine) if len(parts) >= 2 { info.Router = parts[0] // 提取HTTP方法 if len(parts) > 1 { methodPart := parts[1] if strings.HasPrefix(methodPart, "[") && strings.HasSuffix(methodPart, "]") { info.Method = strings.ToUpper(strings.Trim(methodPart, "[]")) } } } } } return info } // GetSummary 根据路径和方法获取Summary func (sp *SwaggerParser) GetSummary(method, path string) string { // 尝试精确匹配 key := fmt.Sprintf("%s %s", strings.ToUpper(method), path) if info, exists := sp.swaggerMap[key]; exists { return info.Summary } // 尝试匹配不带/api前缀的路径 if strings.HasPrefix(path, "/api/") { pathWithoutAPI := strings.TrimPrefix(path, "/api") keyWithoutAPI := fmt.Sprintf("%s %s", strings.ToUpper(method), pathWithoutAPI) if info, exists := sp.swaggerMap[keyWithoutAPI]; exists { return info.Summary } } // 尝试模糊匹配(处理路径参数) for swaggerKey, info := range sp.swaggerMap { if sp.matchRoute(swaggerKey, fmt.Sprintf("%s %s", strings.ToUpper(method), path)) { return info.Summary } } // 尝试匹配转换后的路径(将:var转换为{var}) convertedPath := sp.convertPathFormat(path) if convertedPath != path { convertedKey := fmt.Sprintf("%s %s", strings.ToUpper(method), convertedPath) if info, exists := sp.swaggerMap[convertedKey]; exists { return info.Summary } } return "" } // convertPathFormat 转换路径格式:将:var格式改为{var}格式 func (sp *SwaggerParser) convertPathFormat(path string) string { re := regexp.MustCompile(`:([a-zA-Z0-9_]+)`) return re.ReplaceAllString(path, "{$1}") } // matchRoute 匹配路由(处理路径参数) func (sp *SwaggerParser) matchRoute(pattern, route string) bool { // 将路径参数转换为正则表达式 // 例如:/users/:id -> /users/[^/]+ patternRegex := regexp.MustCompile(`:[a-zA-Z0-9_]+`) regexPattern := patternRegex.ReplaceAllString(pattern, `[^/]+`) // 创建正则表达式 re, err := regexp.Compile("^" + regexPattern + "$") if err != nil { return false } return re.MatchString(route) } // GetAllSwaggerInfo 获取所有Swagger信息 func (sp *SwaggerParser) GetAllSwaggerInfo() map[string]SwaggerInfo { return sp.swaggerMap }