apidoc.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "os"
  7. "regexp"
  8. "scd_check_tools/global"
  9. "scd_check_tools/models/bo"
  10. "scd_check_tools/tools"
  11. "strings"
  12. "github.com/astaxie/beego/orm"
  13. )
  14. //自动分析api接口及定义,并写入权限定义表
  15. type ApiDoc struct {
  16. }
  17. //启动接口分析。建议在系统启动是同步开启
  18. //仅对controller中定义的接口进行分析
  19. //注意:原global_const_code表中的code字段长度设计为30,需要调整为200,以便写入足够长的接口地址。其中的parentcode和name都可以适当加长到100
  20. func (c *ApiDoc) Run() {
  21. gofiles := map[string]string{
  22. "基础服务": "./controllers/apiController.go",
  23. "数据导入导出服务": "./controllers/excelController.go",
  24. "文件服务": "./controllers/attachmentController.go",
  25. "检测任务服务": "./controllers/taskController.go",
  26. "通知提醒服务": "./controllers/noticeController.go",
  27. "规则配置服务": "./controllers/rueController.go",
  28. "SCD校验服务": "./controllers/scdCompController.go",
  29. "SCD可视化服务": "./controllers/screenController.go",
  30. "统计分析服务": "./controllers/statController.go",
  31. "版本及升级管理服务": "./upgrade/versionController.go",
  32. }
  33. db := orm.NewOrm()
  34. db.Raw("ALTER TABLE global_const_code MODIFY COLUMN `code` varchar(200)").Exec()
  35. db.Raw("ALTER TABLE global_const_code MODIFY COLUMN `parentcode` varchar(100)").Exec()
  36. db.Raw("ALTER TABLE global_const_code MODIFY COLUMN `name` varchar(100)").Exec()
  37. code := "pl_service"
  38. db.Raw("insert IGNORE into global_const_code(code,parentcode,name)values(?,?,?)", code, "sysmenu", "接口服务").Exec()
  39. for apiDesc, t1 := range gofiles {
  40. v_servicecodes := strings.Split(strings.ReplaceAll(t1, ".go", ""), "/")
  41. servicecode := v_servicecodes[len(v_servicecodes)-1]
  42. doclist, _ := c.readMethodDocLine(t1)
  43. if len(doclist) > 0 {
  44. fmt.Println(fmt.Sprintf("%s:%+v", apiDesc, doclist))
  45. db.Raw("insert IGNORE into global_const_code(code,parentcode,name)values(?,?,?)", servicecode, "pl_service", apiDesc).Exec()
  46. for _, d := range doclist {
  47. fmt.Println(fmt.Sprintf("%+v", d))
  48. db.Raw("insert IGNORE into global_const_code(code,parentcode,name)values(?,?,?)", d[1], servicecode, d[0]).Exec()
  49. }
  50. }
  51. }
  52. }
  53. //缓存接口定义。在正式环境中启用
  54. func (c *ApiDoc) CacheApiDoc() {
  55. gc := new(bo.Global)
  56. lst, _ := gc.GetChildrenGlobalCode("pl_service")
  57. if len(lst) == 0 {
  58. return
  59. }
  60. for _, r := range lst {
  61. code := tools.IsEmpty(r["code"])
  62. global.ApiDocCache.Store(fmt.Sprintf("apidoc_%s", code), true)
  63. childlst, _ := gc.GetChildrenGlobalCode(code)
  64. if len(childlst) > 0 {
  65. for _, rc := range childlst {
  66. code = tools.IsEmpty(rc["code"])
  67. global.ApiDocCache.Store(fmt.Sprintf("apidoc_%s", code), true)
  68. }
  69. }
  70. }
  71. }
  72. //判断指定的api定义是否存在
  73. func (c *ApiDoc) Exist(api string) bool {
  74. _, h := global.ApiDocCache.Load(fmt.Sprintf("apidoc_%s", api))
  75. return h
  76. }
  77. func (c *ApiDoc) readMethodDocLine(fileName string) ([][]string, error) {
  78. f, err := os.Open(fileName)
  79. if err != nil {
  80. return nil, err
  81. }
  82. buf := bufio.NewReader(f)
  83. var result [][]string
  84. var comments_summary = false
  85. var notAuth = true
  86. comments_summary_text := ""
  87. reg := regexp.MustCompile("\\s+") //去除空白字符,包括空格、tab等
  88. regPostGet := regexp.MustCompile("\\[.*?\\]")
  89. for {
  90. line, err := buf.ReadString('\n')
  91. if err != nil {
  92. if err == io.EOF { //读取结束,会报EOF
  93. return result, nil
  94. }
  95. return nil, err
  96. }
  97. line = reg.ReplaceAllString(line, "")
  98. if strings.HasPrefix(line, "//@NotAuth") {
  99. notAuth = false
  100. }
  101. if strings.HasPrefix(line, "//@Summary") || strings.HasPrefix(line, "//@Title") {
  102. if comments_summary {
  103. continue
  104. }
  105. comments_summary = true
  106. comments_summary_text = line[10:]
  107. }
  108. if strings.HasPrefix(line, "//@router") {
  109. if comments_summary && notAuth {
  110. result = append(result, []string{comments_summary_text, "/api" + regPostGet.ReplaceAllString(line[9:], "")})
  111. }
  112. comments_summary_text = ""
  113. comments_summary = false
  114. notAuth = true
  115. }
  116. }
  117. return result, nil
  118. }