123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- package main
- import (
- "bufio"
- "fmt"
- "io"
- "os"
- "regexp"
- "scd_check_tools/global"
- "scd_check_tools/models/bo"
- "scd_check_tools/tools"
- "strings"
- "github.com/astaxie/beego/orm"
- )
- //自动分析api接口及定义,并写入权限定义表
- type ApiDoc struct {
- }
- //启动接口分析。建议在系统启动是同步开启
- //仅对controller中定义的接口进行分析
- //注意:原global_const_code表中的code字段长度设计为30,需要调整为200,以便写入足够长的接口地址。其中的parentcode和name都可以适当加长到100
- func (c *ApiDoc) Run() {
- gofiles := map[string]string{
- "基础服务": "./controllers/apiController.go",
- "数据导入导出服务": "./controllers/excelController.go",
- "文件服务": "./controllers/attachmentController.go",
- "检测任务服务": "./controllers/taskController.go",
- "通知提醒服务": "./controllers/noticeController.go",
- "规则配置服务": "./controllers/rueController.go",
- "SCD校验服务": "./controllers/scdCompController.go",
- "SCD可视化服务": "./controllers/screenController.go",
- "统计分析服务": "./controllers/statController.go",
- "版本及升级管理服务": "./upgrade/versionController.go",
- }
- db := orm.NewOrm()
- db.Raw("ALTER TABLE global_const_code MODIFY COLUMN `code` varchar(200)").Exec()
- db.Raw("ALTER TABLE global_const_code MODIFY COLUMN `parentcode` varchar(100)").Exec()
- db.Raw("ALTER TABLE global_const_code MODIFY COLUMN `name` varchar(100)").Exec()
- code := "pl_service"
- db.Raw("insert IGNORE into global_const_code(code,parentcode,name)values(?,?,?)", code, "sysmenu", "接口服务").Exec()
- for apiDesc, t1 := range gofiles {
- v_servicecodes := strings.Split(strings.ReplaceAll(t1, ".go", ""), "/")
- servicecode := v_servicecodes[len(v_servicecodes)-1]
- doclist, _ := c.readMethodDocLine(t1)
- if len(doclist) > 0 {
- fmt.Println(fmt.Sprintf("%s:%+v", apiDesc, doclist))
- db.Raw("insert IGNORE into global_const_code(code,parentcode,name)values(?,?,?)", servicecode, "pl_service", apiDesc).Exec()
- for _, d := range doclist {
- fmt.Println(fmt.Sprintf("%+v", d))
- db.Raw("insert IGNORE into global_const_code(code,parentcode,name)values(?,?,?)", d[1], servicecode, d[0]).Exec()
- }
- }
- }
- }
- //缓存接口定义。在正式环境中启用
- func (c *ApiDoc) CacheApiDoc() {
- gc := new(bo.Global)
- lst, _ := gc.GetChildrenGlobalCode("pl_service")
- if len(lst) == 0 {
- return
- }
- for _, r := range lst {
- code := tools.IsEmpty(r["code"])
- global.ApiDocCache.Store(fmt.Sprintf("apidoc_%s", code), true)
- childlst, _ := gc.GetChildrenGlobalCode(code)
- if len(childlst) > 0 {
- for _, rc := range childlst {
- code = tools.IsEmpty(rc["code"])
- global.ApiDocCache.Store(fmt.Sprintf("apidoc_%s", code), true)
- }
- }
- }
- }
- //判断指定的api定义是否存在
- func (c *ApiDoc) Exist(api string) bool {
- _, h := global.ApiDocCache.Load(fmt.Sprintf("apidoc_%s", api))
- return h
- }
- func (c *ApiDoc) readMethodDocLine(fileName string) ([][]string, error) {
- f, err := os.Open(fileName)
- if err != nil {
- return nil, err
- }
- buf := bufio.NewReader(f)
- var result [][]string
- var comments_summary = false
- var notAuth = true
- comments_summary_text := ""
- reg := regexp.MustCompile("\\s+") //去除空白字符,包括空格、tab等
- regPostGet := regexp.MustCompile("\\[.*?\\]")
- for {
- line, err := buf.ReadString('\n')
- if err != nil {
- if err == io.EOF { //读取结束,会报EOF
- return result, nil
- }
- return nil, err
- }
- line = reg.ReplaceAllString(line, "")
- if strings.HasPrefix(line, "//@NotAuth") {
- notAuth = false
- }
- if strings.HasPrefix(line, "//@Summary") || strings.HasPrefix(line, "//@Title") {
- if comments_summary {
- continue
- }
- comments_summary = true
- comments_summary_text = line[10:]
- }
- if strings.HasPrefix(line, "//@router") {
- if comments_summary && notAuth {
- result = append(result, []string{comments_summary_text, "/api" + regPostGet.ReplaceAllString(line[9:], "")})
- }
- comments_summary_text = ""
- comments_summary = false
- notAuth = true
- }
- }
- return result, nil
- }
|