未验证 提交 1973a5b4 编写于 作者: Mr.奇淼('s avatar Mr.奇淼( 提交者: GitHub

Merge pull request #374 from songzhibin97/gva_gormv2_dev

提供自动化代码预览功能
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
......
......@@ -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) // 获取数据库
......
......@@ -16,6 +16,11 @@ import (
"gorm.io/gorm"
)
const (
autoPath = "autoCode/"
basePath = "resource/template"
)
type tplData struct {
template *template.Template
locationPath string
......@@ -23,59 +28,79 @@ type tplData struct {
autoMoveFilePath string
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: CreateTemp
//@description: 创建代码
//@author: [songzhibin97](https://github.com/songzhibin97)
//@function: PreviewTemp
//@description: 预览创建代码
//@param: model.AutoCodeStruct
//@return: error
//@return: map[string]string, error
func CreateTemp(autoCode model.AutoCodeStruct) (err error) {
basePath := "resource/template"
// 获取 basePath 文件夹下所有tpl文件
tplFileList, err := GetAllTplFile(basePath, nil)
func PreviewTemp(autoCode model.AutoCodeStruct) (map[string]string, error) {
dataList, _, needMkdir, err := getNeedList(&autoCode)
if err != nil {
return 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})
return nil, err
}
// 生成 *Template, 填充 template 字段
for index, value := range dataList {
dataList[index].template, err = template.ParseFiles(value.locationPath)
if err != nil {
return err
}
// 写入文件前,先创建文件夹
if err = utils.CreateDir(needMkdir...); 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"
// 创建map
ret := make(map[string]string)
// 生成map
for _, value := range dataList {
ext := ""
if ext = filepath.Ext(value.autoCodePath); ext == ".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:])
}
f, err := os.OpenFile(value.autoCodePath, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
return nil, err
}
if lastSeparator := strings.LastIndex(dataList[index].autoCodePath, string(os.PathSeparator)); lastSeparator != -1 {
needMkdir = append(needMkdir, dataList[index].autoCodePath[:lastSeparator])
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: 创建代码
//@param: model.AutoCodeStruct
//@return: error
func CreateTemp(autoCode model.AutoCodeStruct) (err error) {
dataList, fileList, needMkdir, err := getNeedList(&autoCode)
if err != nil {
return err
}
// 写入文件前,先创建文件夹
if err = utils.CreateDir(needMkdir...); err != nil {
return err
......@@ -83,7 +108,6 @@ func CreateTemp(autoCode model.AutoCodeStruct) (err error) {
// 生成文件
for _, value := range dataList {
fileList = append(fileList, value.autoCodePath)
f, err := os.OpenFile(value.autoCodePath, os.O_CREATE|os.O_WRONLY, 0755)
if err != nil {
return err
......@@ -276,3 +300,53 @@ func AutoCreateApi(a *model.AutoCodeStruct) (err error) {
})
return err
}
func getNeedList(autoCode *model.AutoCodeStruct) (dataList []tplData, fileList []string, needMkdir []string, err error) {
// 获取 basePath 文件夹下所有tpl文件
tplFileList, err := GetAllTplFile(basePath, nil)
if err != nil {
return nil, nil, 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, nil, 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])
}
}
for _, value := range dataList {
fileList = append(fileList, value.autoCodePath)
}
return dataList, fileList, needMkdir, err
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册