提交 b92f4561 编写于 作者: Mr.奇淼('s avatar Mr.奇淼(

自动化后端插件包功能初版完成

上级 392216db
......@@ -211,3 +211,26 @@ func (autoApi *AutoCodeApi) DelPackage(c *gin.Context) {
response.OkWithMessage("删除成功", c)
}
}
// DelPackage
// @Tags AutoCode
// @Summary 创建插件模板
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body system.SysAutoCode true "创建插件模板"
// @Success 200 {object} response.Response{data=map[string]interface{},msg=string} "创建插件模板成功"
// @Router /autoCode/createPlug [post]
func (autoApi *AutoCodeApi) AutoPlug(c *gin.Context) {
var a system.AutoPlugReq
_ = c.ShouldBindJSON(&a)
a.Snake = strings.ToLower(a.PlugName)
a.NeedModel = a.HasRequest || a.HasResponse
err := autoCodeService.CreatePlug(a)
if err != nil {
global.GVA_LOG.Error("预览失败!", zap.Error(err))
response.FailWithMessage("预览失败", c)
} else {
response.Ok(c)
}
}
package system
type AutoPlug struct {
PlugName string `json:"plugName"`
RouterGroup string `json:"routerGroup"`
HasGlobal bool `json:"hasGlobal"`
HasRequest bool `json:"hasRequest"`
HasResponse bool `json:"hasResponse"`
Global []struct {
Key string `json:"key"`
Type string `json:"type"`
} `json:"global"`
Request []struct {
Key string `json:"key"`
Type string `json:"type"`
} `json:"request"`
Response []struct {
Key string `json:"key"`
Type string `json:"type"`
} `json:"response"`
}
......@@ -17,8 +17,8 @@ type AutoCodeStruct struct {
AutoMoveFile bool `json:"autoMoveFile"` // 是否自动移动文件
Fields []*Field `json:"fields"`
DictTypes []string `json:"-"`
Package string `json:"package"`
PackageT string `json:"-"`
Package string `json:"package"`
PackageT string `json:"-"`
}
type Field struct {
......@@ -38,6 +38,31 @@ var AutoMoveErr error = errors.New("创建代码成功并移动文件成功")
type SysAutoCode struct {
global.GVA_MODEL
PackageName string `json:"packageName" gorm:"comment:包名"`
Label string `json:"label" gorm:"comment:展示名"`
Label string `json:"label" gorm:"comment:展示名"`
Desc string `json:"desc" gorm:"comment:描述"`
}
type AutoPlugReq struct {
PlugName string `json:"plugName"` // 必然大写开头
Snake string `json:"snake"` // 后端自动转为 snake
RouterGroup string `json:"routerGroup"`
HasGlobal bool `json:"hasGlobal"`
HasRequest bool `json:"hasRequest"`
HasResponse bool `json:"hasResponse"`
NeedModel bool `json:"needModel"`
Global []struct {
Key string `json:"key"`
Type string `json:"type"`
Desc string `json:"desc"`
} `json:"global"`
Request []struct {
Key string `json:"key"`
Type string `json:"type"`
Desc string `json:"desc"`
} `json:"request"`
Response []struct {
Key string `json:"key"`
Type string `json:"type"`
Desc string `json:"desc"`
} `json:"response"`
}
package api
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
{{ if .NeedModel }} "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/model" {{ end }}
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type {{ .PlugName}}Api struct{}
// @Tags {{ .PlugName}}
// @Summary 请手动填写接口功能
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
// @Router /{{ .RouterGroup}}/routerName[post]
func (p *{{ .PlugName}}Api) ApiName(c *gin.Context) {
{{- if .HasRequest}}
var plug model.Request
_ = c.ShouldBindJSON(&plug)
{{ end -}}
if err{{- if .HasResponse }},res {{ end -}}:= service.ServiceGroupApp.PlugService({{ if .HasRequest }}plug{{ end -}}); err != nil {
global.GVA_LOG.Error("失败!", zap.Error(err))
response.FailWithMessage("失败", c)
} else {
{{if .HasResponse }}
response.OkWithDetailed(res,"成功",c)
{{else}}
response.OkWithData("成功", c)
{{ end -}}
}
}
package api
type ApiGroup struct {
AliSmsApi
{{ .PlugName}}Api
}
var ApiGroupApp = new(ApiGroup)
package config
{{- if .HasGlobal }}
type {{ .PlugName }} struct {
{{- range .Global }}
{{ .Key }} {{ .Type }} {{- if ne .Desc "" }} // {{ .Desc }} {{ end -}}
{{- end }}
}
{{ end -}}
\ No newline at end of file
package global
{{- if .HasGlobal }}
import "github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/config"
var GlobalConfig = new(config.{{ .PlugName}})
{{ end -}}
\ No newline at end of file
package plug
package {{ .Snake}}
import (
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .PlugName}}/global"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .PlugName}}/router"
{{- if .HasGlobal }}
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/global"
{{- end }}
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/router"
"github.com/gin-gonic/gin"
)
type {{ .PlugName}}Plugin struct {
}
func Create{{ .PlugName}}Plug() ({{- range .Global}} {{.Key}} {{.Type}} {{- end }})*{{ .PlugName}}Plugin {
func Create{{ .PlugName}}Plug({{- range .Global}} {{.Key}} {{.Type}} {{- end }})*{{ .PlugName}}Plugin {
{{- if .HasGlobal }}
{{- range .Global}}
global.GlobalConfig.{{.Key}} = {{.Key}}
{{- end }}
{{ end }}
return &{{ .PlugName}}Plugin{}
}
......
package model
{{- if .HasRequest }}
type Request struct {
{{- range .Request }}
{{ .Key }} {{ .Type }} {{- if ne .Desc "" }} // {{ .Desc }} {{ end -}}
{{- end }}
}
{{ end -}}
{{- if .HasResponse }}
type Response struct {
{{- range .Response }}
{{ .Key }} {{ .Type }} {{- if ne .Desc "" }} // {{ .Desc }} {{ end -}}
{{- end }}
}
{{ end -}}
package router
type RouterGroup struct {
AliSmsRouter
{{ .PlugName}}Router
}
var RouterGroupApp = new(RouterGroup)
package router
import (
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/api"
"github.com/gin-gonic/gin"
)
type {{ .PlugName}}Router struct {
}
func (s *{{ .PlugName}}Router) Init{{ .PlugName}}Router(Router *gin.RouterGroup) {
plugRouter := Router
plugApi := api.ApiGroupApp.{{ .PlugName}}Api
{
plugRouter.POST("routerName", plugApi.ApiName)
}
}
package service
type ServiceGroup struct {
AliSmsService
{{ .PlugName}}Service
}
var ServiceGroupApp = new(ServiceGroup)
package service
{{- if .NeedModel }}
import (
"github.com/flipped-aurora/gin-vue-admin/server/plugin/{{ .Snake}}/model"
)
{{ end }}
type {{ .PlugName}}Service struct{}
func (e *{{ .PlugName}}Service) PlugService({{- if .HasRequest }}req model.Request {{ end -}}) (err error{{- if .HasResponse }},res model.Response{{ end -}}) {
// 写你的业务逻辑
return nil{{- if .HasResponse }},res {{ end }}
}
package api
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/sms/model"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/sms/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
type AliSmsApi struct{}
// @Tags System
// @Summary 发送(阿里)短信
// @Security ApiKeyAuth
// @Produce application/json
// @Success 200 {string} string "{"success":true,"data":{},"msg":"发送成功"}"
// @Router /aliSms/sendAliSms[post]
func (s *AliSmsApi) SendAliSms(c *gin.Context) {
var ali model.AliModel
_ = c.ShouldBindJSON(&ali)
if err := service.ServiceGroupApp.SendAliSms(ali.Phones, ali.TemplateCode, ali.TemplateParam); err != nil {
global.GVA_LOG.Error("发送失败!", zap.Error(err))
response.FailWithMessage("发送失败", c)
} else {
response.OkWithData("发送成功", c)
}
}
package config
type AliSms struct {
AccessKeyId string `mapstructure:"accessKeyId" json:"accessKeyId" yaml:"accessKeyId"` // 短信的AccessKey ID
AccessSecret string `mapstructure:"accessSecret" json:"accessSecret" yaml:"accessSecret"` // 短信的AccessKey Secret
SignName string `mapstructure:"signName" json:"signName" yaml:"signName"` // 短信的 SignName
}
package global
import "github.com/flipped-aurora/gin-vue-admin/server/plugin/sms/config"
var GlobalConfig = new(config.AliSms)
package model
type AliModel struct {
Phones []string `json:"phones"`
TemplateCode string `json:"templateCode"`
TemplateParam string `json:"templateParam"`
}
package router
import (
"github.com/flipped-aurora/gin-vue-admin/server/plugin/sms/api"
"github.com/gin-gonic/gin"
)
type AliSmsRouter struct {
}
func (s *AliSmsRouter) InitAliSmsRouter(Router *gin.RouterGroup) {
emailRouter := Router
aliSmsApi := api.ApiGroupApp.AliSmsApi
{
emailRouter.POST("sendSms", aliSmsApi.SendAliSms) // 发送测试邮件
}
}
package service
import (
"errors"
openapi "github.com/alibabacloud-go/darabonba-openapi/client"
dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v2/client"
"github.com/alibabacloud-go/tea/tea"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/sms/global"
"strings"
)
type AliSmsService struct{}
/**
* 使用AK&SK初始化账号Client
* @param accessKeyId
* @param accessKeySecret
* @return Client
* @throws Exception
*/
func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *dysmsapi20170525.Client, _err error) {
config := &openapi.Config{
// 您的AccessKey ID
AccessKeyId: accessKeyId,
// 您的AccessKey Secret
AccessKeySecret: accessKeySecret,
}
// 访问的域名
config.Endpoint = tea.String("dysmsapi.aliyuncs.com")
_result = &dysmsapi20170525.Client{}
_result, _err = dysmsapi20170525.NewClient(config)
return _result, _err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: SendAliSms
//@description: 发送(阿里)短信
//@return: err error
// 模板使用json字符串 {"code":"xxx"} 对应你模板里面的变量key和value
func (e *AliSmsService) SendAliSms(phones []string, templateCode string, templateParam string) (err error) {
client, _err := CreateClient(tea.String(global.GlobalConfig.AccessKeyId), tea.String(global.GlobalConfig.AccessSecret))
if _err != nil {
return _err
}
if len(phones) == 0 {
return errors.New("请输入手机号")
}
phonesStr := strings.Join(phones, ",")
sendSmsRequest := &dysmsapi20170525.SendSmsRequest{
SignName: tea.String(global.GlobalConfig.SignName),
PhoneNumbers: tea.String(phonesStr),
TemplateCode: tea.String(templateCode),
TemplateParam: tea.String(templateParam),
}
// 复制代码运行请自行打印 API 的返回值
_, _err = client.SendSms(sendSmsRequest)
if _err != nil {
return _err
}
return _err
}
......@@ -11,13 +11,14 @@ func (s *AutoCodeRouter) InitAutoCodeRouter(Router *gin.RouterGroup) {
autoCodeRouter := Router.Group("autoCode")
autoCodeApi := v1.ApiGroupApp.SystemApiGroup.AutoCodeApi
{
autoCodeRouter.GET("getDB", autoCodeApi.GetDB) // 获取数据库
autoCodeRouter.GET("getTables", autoCodeApi.GetTables) // 获取对应数据库的表
autoCodeRouter.GET("getColumn", autoCodeApi.GetColumn) // 获取指定表所有字段信息
autoCodeRouter.POST("preview", autoCodeApi.PreviewTemp) // 获取自动创建代码预览
autoCodeRouter.POST("createTemp", autoCodeApi.CreateTemp) // 创建自动化代码
autoCodeRouter.POST("createPackage",autoCodeApi.CreatePackage) // 创建package包
autoCodeRouter.POST("getPackage",autoCodeApi.GetPackage) // 获取package包
autoCodeRouter.POST("delPackage",autoCodeApi.DelPackage) // 删除package包
autoCodeRouter.GET("getDB", autoCodeApi.GetDB) // 获取数据库
autoCodeRouter.GET("getTables", autoCodeApi.GetTables) // 获取对应数据库的表
autoCodeRouter.GET("getColumn", autoCodeApi.GetColumn) // 获取指定表所有字段信息
autoCodeRouter.POST("preview", autoCodeApi.PreviewTemp) // 获取自动创建代码预览
autoCodeRouter.POST("createTemp", autoCodeApi.CreateTemp) // 创建自动化代码
autoCodeRouter.POST("createPackage", autoCodeApi.CreatePackage) // 创建package包
autoCodeRouter.POST("getPackage", autoCodeApi.GetPackage) // 获取package包
autoCodeRouter.POST("delPackage", autoCodeApi.DelPackage) // 删除package包
autoCodeRouter.POST("createPlug", autoCodeApi.AutoPlug) // 自动插件包模板
}
}
......@@ -17,7 +17,7 @@ import (
"strings"
"text/template"
"github.com/flipped-aurora/gin-vue-admin/server/resource/template/subcontract"
"github.com/flipped-aurora/gin-vue-admin/server/resource/autocode_template/subcontract"
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/system"
......@@ -28,7 +28,8 @@ import (
const (
autoPath = "autocode_template/"
basePath = "resource/template"
autocodePath = "resource/autocode_template"
plugPath = "resource/plug_template"
packageService = "service/%s/enter.go"
packageServiceName = "service"
packageRouter = "router/%s/enter.go"
......@@ -483,7 +484,7 @@ func (autoCodeService *AutoCodeService) getNeedList(autoCode *system.AutoCodeStr
utils.TrimSpace(field)
}
// 获取 basePath 文件夹下所有tpl文件
tplFileList, err := autoCodeService.GetAllTplFile(basePath, nil)
tplFileList, err := autoCodeService.GetAllTplFile(autocodePath, nil)
if err != nil {
return nil, nil, nil, err
}
......@@ -505,7 +506,7 @@ func (autoCodeService *AutoCodeService) getNeedList(autoCode *system.AutoCodeStr
// resource/template/web/api.js.tpl -> autoCode/web/autoCode.PackageName/api/autoCode.PackageName.js
// resource/template/readme.txt.tpl -> autoCode/readme.txt
for index, value := range dataList {
trimBase := strings.TrimPrefix(value.locationPath, basePath+"/")
trimBase := strings.TrimPrefix(value.locationPath, autocodePath+"/")
if trimBase == "readme.txt.tpl" {
dataList[index].autoCodePath = autoPath + "readme.txt"
continue
......@@ -789,3 +790,21 @@ func ImportReference(filepath, importCode, structName, packageName, groupName st
// 写回数据
return ioutil.WriteFile(filepath, buffer.Bytes(), 0o600)
}
// 自动创建插件模板
func (autoCodeService *AutoCodeService) CreatePlug(plug system.AutoPlugReq) error {
tplFileList, _ := autoCodeService.GetAllTplFile(plugPath, nil)
for _, tpl := range tplFileList {
temp, err := template.ParseFiles(tpl)
fmt.Println(err)
pathArr := strings.SplitAfter(tpl, "/")
if strings.Index(pathArr[2], "tpl") < 0 {
os.MkdirAll("./plugin/"+plug.Snake+"/"+pathArr[2], 0755)
}
f, _ := os.OpenFile("./plugin/"+plug.Snake+"/"+tpl[len(plugPath):len(tpl)-4], os.O_WRONLY|os.O_CREATE, 0666)
e := temp.Execute(f, plug)
fmt.Println(e, f)
defer f.Close()
}
return nil
}
......@@ -115,3 +115,12 @@ export const deletePackageApi = (data) => {
data
})
}
export const createPlugApi = (data) => {
return service({
url: '/autoCode/createPlug',
method: 'post',
data
})
}
......@@ -6,7 +6,7 @@
<el-input v-model="form.plugName" />
</el-form-item>
<el-form-item label="路由组">
<el-input v-model="form.routerGloup" />
<el-input v-model="form.routerGroup" />
</el-form-item>
<el-form-item label="使用全局属性">
<el-checkbox v-model="form.hasGloabl" />
......@@ -19,6 +19,9 @@
<span>
<el-input v-model="i.type" placeholder="type" />
</span>
<span>
<el-input v-model="i.desc" placeholder="备注" />
</span>
<span>
<el-button :icon="Plus" circle @click="addkv(form.global)" />
</span>
......@@ -38,6 +41,9 @@
<span>
<el-input v-model="i.type" placeholder="type" />
</span>
<span>
<el-input v-model="i.desc" placeholder="备注" />
</span>
<span>
<el-button :icon="Plus" circle @click="addkv(form.request)" />
</span>
......@@ -57,6 +63,9 @@
<span>
<el-input v-model="i.type" placeholder="type" />
</span>
<span>
<el-input v-model="i.desc" placeholder="备注" />
</span>
<span>
<el-button :icon="Plus" circle @click="addkv(form.response)" />
</span>
......@@ -65,6 +74,9 @@
</span>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="createPlug">创建</el-button>
</el-form-item>
</el-form>
</div>
</div>
......@@ -75,7 +87,9 @@ import {
Plus,
Minus
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import { createPlugApi } from '@/api/autoCode.js'
import { reactive } from 'vue'
......@@ -88,17 +102,27 @@ const form = reactive({
global: [{
key: '',
type: '',
desc: '',
}],
request: [{
key: '',
type: '',
desc: '',
}],
response: [{
key: '',
type: '',
desc: '',
}]
})
const createPlug = async() => {
const res = await createPlugApi(form)
if (res.code === 0) {
ElMessageBox('创建成功,插件已自动写入后端plugin目录下,请按照自己的逻辑进行创造')
}
}
const addkv = (arr) => {
arr.push({
key: '',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册