Parcourir la source

自动生成代码新增预览接口

songzhibin97 il y a 4 ans
Parent
commit
457e9bb2f6
3 fichiers modifiés avec 142 ajouts et 3 suppressions
  1. 38 3
      server/api/v1/sys_auto_code.go
  2. 1 0
      server/router/sys_auto_code.go
  3. 103 0
      server/service/sys_auto_code.go

+ 38 - 3
server/api/v1/sys_auto_code.go

@@ -1,19 +1,54 @@
 package v1
 
 import (
+	"errors"
 	"fmt"
 	"gin-vue-admin/global"
 	"gin-vue-admin/model"
 	"gin-vue-admin/model/response"
 	"gin-vue-admin/service"
 	"gin-vue-admin/utils"
-	"github.com/gin-gonic/gin"
-	"github.com/pkg/errors"
-	"go.uber.org/zap"
 	"net/url"
 	"os"
+
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
 )
 
+// @Tags AutoCode
+// @Summary 预览创建后的代码
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body model.AutoCodeStruct true "预览创建代码"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
+// @Router /autoCode/preview [post]
+func PreviewTemp(c *gin.Context) {
+	var a model.AutoCodeStruct
+	_ = c.ShouldBindJSON(&a)
+	if err := utils.Verify(a, utils.AutoCodeVerify); err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	if a.AutoCreateApiToSql {
+		if err := service.AutoCreateApi(&a); err != nil {
+			global.GVA_LOG.Error("自动化创建失败!请自行清空垃圾数据!", zap.Any("err", err))
+			c.Writer.Header().Add("success", "false")
+			c.Writer.Header().Add("msg", url.QueryEscape("自动化创建失败!请自行清空垃圾数据!"))
+			return
+		}
+	}
+	m, err := service.PreviewTemp(a)
+	if err != nil {
+		c.Writer.Header().Add("success", "false")
+		c.Writer.Header().Add("msg", url.QueryEscape(err.Error()))
+	} else {
+		c.Writer.Header().Add("Content-Type", "application/json")
+		c.Writer.Header().Add("success", "true")
+		c.JSON(200, m)
+	}
+}
+
 // @Tags AutoCode
 // @Summary 自动代码模板
 // @Security ApiKeyAuth

+ 1 - 0
server/router/sys_auto_code.go

@@ -8,6 +8,7 @@ import (
 func InitAutoCodeRouter(Router *gin.RouterGroup) {
 	AutoCodeRouter := Router.Group("autoCode")
 	{
+		AutoCodeRouter.POST("preview", v1.PreviewTemp)   // 获取自动创建代码预览
 		AutoCodeRouter.POST("createTemp", v1.CreateTemp) // 创建自动化代码
 		AutoCodeRouter.GET("getTables", v1.GetTables)    // 获取对应数据库的表
 		AutoCodeRouter.GET("getDB", v1.GetDB)            // 获取数据库

+ 103 - 0
server/service/sys_auto_code.go

@@ -23,6 +23,109 @@ type tplData struct {
 	autoMoveFilePath string
 }
 
+//@author: [songzhibin97](https://github.com/songzhibin97)
+//@function: PreviewTemp
+//@description: 预览创建代码
+//@param: model.AutoCodeStruct
+//@return: map[string]string, error
+
+func PreviewTemp(autoCode model.AutoCodeStruct) (map[string]string, error) {
+	basePath := "resource/template"
+	// 获取 basePath 文件夹下所有tpl文件
+	tplFileList, err := GetAllTplFile(basePath, nil)
+	if err != nil {
+		return nil, err
+	}
+	dataList := make([]tplData, 0, len(tplFileList))
+	fileList := make([]string, 0, len(tplFileList))
+	needMkdir := make([]string, 0, len(tplFileList)) // 当文件夹下存在多个tpl文件时,改为map更合理
+	// 根据文件路径生成 tplData 结构体,待填充数据
+	for _, value := range tplFileList {
+		dataList = append(dataList, tplData{locationPath: value})
+	}
+	// 生成 *Template, 填充 template 字段
+	for index, value := range dataList {
+		dataList[index].template, err = template.ParseFiles(value.locationPath)
+		if err != nil {
+			return nil, err
+		}
+	}
+	// 生成文件路径,填充 autoCodePath 字段,readme.txt.tpl不符合规则,需要特殊处理
+	// resource/template/web/api.js.tpl -> autoCode/web/autoCode.PackageName/api/autoCode.PackageName.js
+	// resource/template/readme.txt.tpl -> autoCode/readme.txt
+	autoPath := "autoCode/"
+	for index, value := range dataList {
+		trimBase := strings.TrimPrefix(value.locationPath, basePath+"/")
+		if trimBase == "readme.txt.tpl" {
+			dataList[index].autoCodePath = autoPath + "readme.txt"
+			continue
+		}
+
+		if lastSeparator := strings.LastIndex(trimBase, "/"); lastSeparator != -1 {
+			origFileName := strings.TrimSuffix(trimBase[lastSeparator+1:], ".tpl")
+			firstDot := strings.Index(origFileName, ".")
+			if firstDot != -1 {
+				dataList[index].autoCodePath = filepath.Join(autoPath, trimBase[:lastSeparator], autoCode.PackageName,
+					origFileName[:firstDot], autoCode.PackageName+origFileName[firstDot:])
+			}
+		}
+
+		if lastSeparator := strings.LastIndex(dataList[index].autoCodePath, string(os.PathSeparator)); lastSeparator != -1 {
+			needMkdir = append(needMkdir, dataList[index].autoCodePath[:lastSeparator])
+		}
+	}
+
+	// 写入文件前,先创建文件夹
+	if err = utils.CreateDir(needMkdir...); err != nil {
+		return nil, err
+	}
+
+	// 创建map
+	ret := make(map[string]string)
+
+	// 生成map
+	for _, value := range dataList {
+		ext := ""
+		if ext = filepath.Ext(value.autoCodePath); ext == ".txt" {
+			continue
+		}
+		fileList = append(fileList, value.autoCodePath)
+		f, err := os.OpenFile(value.autoCodePath, os.O_CREATE|os.O_WRONLY, 0755)
+		if err != nil {
+			return nil, err
+		}
+		if err = value.template.Execute(f, autoCode); err != nil {
+			return nil, err
+		}
+		_ = f.Close()
+		f, err = os.OpenFile(value.autoCodePath, os.O_CREATE|os.O_RDONLY, 0755)
+		if err != nil {
+			return nil, err
+		}
+		builder := strings.Builder{}
+		builder.WriteString("```\n")
+		data, err := ioutil.ReadAll(f)
+		if err != nil {
+			return nil, err
+		}
+		builder.Write(data)
+		builder.WriteString("\n```")
+		if ext != "" && strings.Contains(ext, ".") {
+			builder.WriteString(strings.Replace(ext, ".", "", -1))
+		}
+
+		ret[value.autoCodePath] = builder.String()
+		_ = f.Close()
+
+	}
+	defer func() { // 移除中间文件
+		if err := os.RemoveAll(autoPath); err != nil {
+			return
+		}
+	}()
+	return ret, nil
+}
+
 //@author: [piexlmax](https://github.com/piexlmax)
 //@function: CreateTemp
 //@description: 创建代码