2023-01-18 16:23:39 +08:00
|
|
|
|
// Package hggen
|
|
|
|
|
// @Link https://github.com/bufanyun/hotgo
|
2023-02-23 17:53:04 +08:00
|
|
|
|
// @Copyright Copyright (c) 2023 HotGo CLI
|
2023-01-18 16:23:39 +08:00
|
|
|
|
// @Author Ms <133814250@qq.com>
|
|
|
|
|
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
|
|
|
|
package hggen
|
|
|
|
|
|
|
|
|
|
import (
|
2024-04-22 23:08:40 +08:00
|
|
|
|
"github.com/gogf/gf/v2/os/gfile"
|
2023-07-20 18:01:10 +08:00
|
|
|
|
_ "hotgo/internal/library/hggen/internal/cmd/gendao"
|
2024-04-22 23:08:40 +08:00
|
|
|
|
"hotgo/internal/library/hggen/internal/utility/utils"
|
2023-07-20 18:01:10 +08:00
|
|
|
|
_ "unsafe"
|
|
|
|
|
|
2023-01-18 16:23:39 +08:00
|
|
|
|
"context"
|
|
|
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
|
|
|
"github.com/gogf/gf/v2/frame/g"
|
|
|
|
|
"github.com/gogf/gf/v2/util/gconv"
|
|
|
|
|
"hotgo/internal/consts"
|
2023-02-23 17:53:04 +08:00
|
|
|
|
"hotgo/internal/library/addons"
|
2023-01-18 16:23:39 +08:00
|
|
|
|
"hotgo/internal/library/hggen/internal/cmd"
|
|
|
|
|
"hotgo/internal/library/hggen/internal/cmd/gendao"
|
2023-02-23 17:53:04 +08:00
|
|
|
|
"hotgo/internal/library/hggen/internal/cmd/genservice"
|
2023-01-18 16:23:39 +08:00
|
|
|
|
"hotgo/internal/library/hggen/views"
|
2023-02-08 20:29:34 +08:00
|
|
|
|
"hotgo/internal/model"
|
2023-01-18 16:23:39 +08:00
|
|
|
|
"hotgo/internal/model/input/form"
|
|
|
|
|
"hotgo/internal/model/input/sysin"
|
|
|
|
|
"hotgo/internal/service"
|
|
|
|
|
"sort"
|
|
|
|
|
)
|
|
|
|
|
|
2023-07-20 18:01:10 +08:00
|
|
|
|
//go:linkname doGenDaoForArray hotgo/internal/library/hggen/internal/cmd/gendao.doGenDaoForArray
|
|
|
|
|
func doGenDaoForArray(ctx context.Context, index int, in gendao.CGenDaoInput)
|
|
|
|
|
|
2023-01-18 16:23:39 +08:00
|
|
|
|
// Dao 生成数据库实体
|
|
|
|
|
func Dao(ctx context.Context) (err error) {
|
2024-04-22 23:08:40 +08:00
|
|
|
|
|
|
|
|
|
// 在执行gf gen dao时,先将生成文件放在临时路径,生成完成后再拷贝到项目
|
|
|
|
|
// 目的是希望减少触发gf热编译的几率,防止热编译运行时代码生成流程未结束被自动重启打断
|
|
|
|
|
// gf gen dao 的执行时长主要取决于需要生成数据库表的数量,表越多速度越慢
|
|
|
|
|
tempPathPrefix := views.GetTempGeneratePath(ctx) + "/dao"
|
|
|
|
|
|
2023-01-18 16:23:39 +08:00
|
|
|
|
for _, v := range daoConfig {
|
|
|
|
|
inp := defaultGenDaoInput
|
2024-04-22 23:08:40 +08:00
|
|
|
|
if err = gconv.Scan(v, &inp); err != nil {
|
2023-01-18 16:23:39 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
2024-04-22 23:08:40 +08:00
|
|
|
|
oldPath := inp.Path
|
|
|
|
|
inp.ImportPrefix = utils.GetImportPath(inp.Path)
|
|
|
|
|
inp.Path = tempPathPrefix + "/" + inp.Path
|
|
|
|
|
|
|
|
|
|
if err = gfile.Remove(inp.Path); err != nil {
|
|
|
|
|
err = gerror.Newf("清理临时生成目录失败:%v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err = gfile.Mkdir(inp.Path); err != nil {
|
|
|
|
|
err = gerror.Newf("创建临时生成目录失败:%v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-20 18:01:10 +08:00
|
|
|
|
doGenDaoForArray(ctx, -1, inp)
|
2024-04-22 23:08:40 +08:00
|
|
|
|
|
|
|
|
|
if err = gfile.CopyDir(inp.Path, gfile.Pwd()+"/"+oldPath); err != nil {
|
|
|
|
|
err = gerror.Newf("拷贝生成文件失败:%v", err)
|
|
|
|
|
return err
|
|
|
|
|
}
|
2023-01-18 16:23:39 +08:00
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Service 生成业务接口
|
|
|
|
|
func Service(ctx context.Context) (err error) {
|
2023-02-23 17:53:04 +08:00
|
|
|
|
return ServiceWithCfg(ctx, GetServiceConfig())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ServiceWithCfg 生成业务接口
|
|
|
|
|
func ServiceWithCfg(ctx context.Context, cfg ...genservice.CGenServiceInput) (err error) {
|
|
|
|
|
c := GetServiceConfig()
|
|
|
|
|
if len(cfg) > 0 {
|
|
|
|
|
c = cfg[0]
|
|
|
|
|
}
|
|
|
|
|
_, err = cmd.Gen.Service(ctx, c)
|
2023-01-18 16:23:39 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TableColumns 获取指定表生成字段列表
|
2023-07-20 18:01:10 +08:00
|
|
|
|
func TableColumns(ctx context.Context, in *sysin.GenCodesColumnListInp) (fields []*sysin.GenCodesColumnListModel, err error) {
|
2023-01-18 16:23:39 +08:00
|
|
|
|
return views.DoTableColumns(ctx, in, GetDaoConfig(in.Name))
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-20 18:01:10 +08:00
|
|
|
|
func TableSelects(ctx context.Context, in *sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error) {
|
2023-01-18 16:23:39 +08:00
|
|
|
|
res = new(sysin.GenCodesSelectsModel)
|
2023-02-09 13:53:19 +08:00
|
|
|
|
res.GenType, err = GenTypeSelect(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
2023-01-18 16:23:39 +08:00
|
|
|
|
}
|
2023-02-09 13:53:19 +08:00
|
|
|
|
|
2023-01-18 16:23:39 +08:00
|
|
|
|
res.Db = DbSelect(ctx)
|
|
|
|
|
|
|
|
|
|
for k, v := range consts.GenCodesStatusNameMap {
|
|
|
|
|
res.Status = append(res.Status, &form.Select{
|
|
|
|
|
Value: k,
|
|
|
|
|
Name: v,
|
|
|
|
|
Label: v,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(res.Status)
|
|
|
|
|
|
|
|
|
|
for k, v := range consts.GenCodesJoinNameMap {
|
|
|
|
|
res.LinkMode = append(res.LinkMode, &form.Select{
|
|
|
|
|
Value: k,
|
|
|
|
|
Name: v,
|
|
|
|
|
Label: v,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(res.LinkMode)
|
|
|
|
|
|
|
|
|
|
for k, v := range consts.GenCodesBuildMethNameMap {
|
|
|
|
|
res.BuildMeth = append(res.BuildMeth, &form.Select{
|
|
|
|
|
Value: k,
|
|
|
|
|
Name: v,
|
|
|
|
|
Label: v,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(res.BuildMeth)
|
|
|
|
|
|
|
|
|
|
for _, v := range views.FormModes {
|
|
|
|
|
res.FormMode = append(res.FormMode, &form.Select{
|
|
|
|
|
Value: v,
|
|
|
|
|
Name: views.FormModeMap[v],
|
|
|
|
|
Label: views.FormModeMap[v],
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(res.FormMode)
|
|
|
|
|
|
|
|
|
|
for k, v := range views.FormRoleMap {
|
|
|
|
|
res.FormRole = append(res.FormRole, &form.Select{
|
|
|
|
|
Value: k,
|
|
|
|
|
Name: v,
|
|
|
|
|
Label: v,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(res.FormRole)
|
|
|
|
|
|
2023-07-20 18:01:10 +08:00
|
|
|
|
dictMode, err := service.SysDictType().TreeSelect(ctx, &sysin.DictTreeSelectInp{})
|
2023-02-09 13:53:19 +08:00
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
2023-01-18 16:23:39 +08:00
|
|
|
|
res.DictMode = dictMode
|
2023-02-09 13:53:19 +08:00
|
|
|
|
|
2023-01-18 16:23:39 +08:00
|
|
|
|
for _, v := range views.WhereModes {
|
|
|
|
|
res.WhereMode = append(res.WhereMode, &form.Select{
|
|
|
|
|
Value: v,
|
|
|
|
|
Name: v,
|
|
|
|
|
Label: v,
|
|
|
|
|
})
|
|
|
|
|
}
|
2024-04-22 23:08:40 +08:00
|
|
|
|
for _, v := range views.TableAligns {
|
|
|
|
|
res.TableAlign = append(res.TableAlign, &form.Select{
|
|
|
|
|
Value: v,
|
|
|
|
|
Name: views.TableAlignMap[v],
|
|
|
|
|
Label: views.TableAlignMap[v],
|
|
|
|
|
})
|
|
|
|
|
}
|
2023-01-18 16:23:39 +08:00
|
|
|
|
|
2023-02-23 17:53:04 +08:00
|
|
|
|
res.Addons = addons.ModuleSelect()
|
2024-04-22 23:08:40 +08:00
|
|
|
|
res.TreeStyleType = consts.GenCodesTreeStyleTypeOptions
|
2023-01-18 16:23:39 +08:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-09 13:53:19 +08:00
|
|
|
|
// GenTypeSelect 获取生成类型选项
|
|
|
|
|
func GenTypeSelect(ctx context.Context) (res sysin.GenTypeSelects, err error) {
|
|
|
|
|
for k, v := range consts.GenCodesTypeNameMap {
|
|
|
|
|
row := &sysin.GenTypeSelect{
|
|
|
|
|
Value: k,
|
|
|
|
|
Name: v,
|
|
|
|
|
Label: v,
|
2023-02-23 17:53:04 +08:00
|
|
|
|
Templates: make(sysin.GenTemplateSelects, 0),
|
2023-02-09 13:53:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
confName, ok := consts.GenCodesTypeConfMap[k]
|
|
|
|
|
if ok {
|
|
|
|
|
var temps []*model.GenerateAppCrudTemplate
|
|
|
|
|
err = g.Cfg().MustGet(ctx, "hggen.application."+confName+".templates").Scan(&temps)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if len(temps) > 0 {
|
|
|
|
|
for index, temp := range temps {
|
2023-02-23 17:53:04 +08:00
|
|
|
|
row.Templates = append(row.Templates, &sysin.GenTemplateSelect{
|
|
|
|
|
Value: index,
|
|
|
|
|
Label: temp.Group,
|
|
|
|
|
Name: temp.Group,
|
|
|
|
|
IsAddon: temp.IsAddon,
|
2023-02-09 13:53:19 +08:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(row.Templates)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = append(res, row)
|
|
|
|
|
}
|
|
|
|
|
sort.Sort(res)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-18 16:23:39 +08:00
|
|
|
|
// DbSelect db选项
|
|
|
|
|
func DbSelect(ctx context.Context) (res form.Selects) {
|
|
|
|
|
dbs := g.Cfg().MustGet(ctx, "hggen.selectDbs")
|
|
|
|
|
if len(dbs.Strings()) == 0 {
|
|
|
|
|
res = make(form.Selects, 0)
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, v := range dbs.Strings() {
|
|
|
|
|
res = append(res, &form.Select{
|
|
|
|
|
Value: v,
|
|
|
|
|
Label: v,
|
|
|
|
|
Name: v,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
return res
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Preview 生成预览
|
2023-07-20 18:01:10 +08:00
|
|
|
|
func Preview(ctx context.Context, in *sysin.GenCodesPreviewInp) (res *sysin.GenCodesPreviewModel, err error) {
|
2023-01-18 16:23:39 +08:00
|
|
|
|
genConfig, err := service.SysConfig().GetLoadGenerate(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch in.GenType {
|
2024-04-22 23:08:40 +08:00
|
|
|
|
case consts.GenCodesTypeCurd, consts.GenCodesTypeTree:
|
2023-01-18 16:23:39 +08:00
|
|
|
|
return views.Curd.DoPreview(ctx, &views.CurdPreviewInput{
|
|
|
|
|
In: in,
|
|
|
|
|
DaoConfig: GetDaoConfig(in.DbName),
|
|
|
|
|
Config: genConfig,
|
|
|
|
|
})
|
|
|
|
|
case consts.GenCodesTypeQueue:
|
|
|
|
|
err = gerror.Newf("生成类型开发中!")
|
|
|
|
|
return
|
|
|
|
|
default:
|
|
|
|
|
err = gerror.Newf("生成类型暂不支持!")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build 提交生成
|
2023-07-20 18:01:10 +08:00
|
|
|
|
func Build(ctx context.Context, in *sysin.GenCodesBuildInp) (err error) {
|
2023-01-18 16:23:39 +08:00
|
|
|
|
genConfig, err := service.SysConfig().GetLoadGenerate(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch in.GenType {
|
2024-04-22 23:08:40 +08:00
|
|
|
|
case consts.GenCodesTypeCurd, consts.GenCodesTypeTree:
|
2023-07-20 18:01:10 +08:00
|
|
|
|
pin := &sysin.GenCodesPreviewInp{SysGenCodes: in.SysGenCodes}
|
2023-01-18 16:23:39 +08:00
|
|
|
|
return views.Curd.DoBuild(ctx, &views.CurdBuildInput{
|
|
|
|
|
PreviewIn: &views.CurdPreviewInput{
|
2023-02-23 17:53:04 +08:00
|
|
|
|
In: pin,
|
2023-01-18 16:23:39 +08:00
|
|
|
|
DaoConfig: GetDaoConfig(in.DbName),
|
|
|
|
|
Config: genConfig,
|
|
|
|
|
},
|
|
|
|
|
BeforeEvent: views.CurdBuildEvent{"runDao": Dao},
|
2023-02-23 17:53:04 +08:00
|
|
|
|
AfterEvent: views.CurdBuildEvent{"runService": func(ctx context.Context) (err error) {
|
|
|
|
|
cfg := GetServiceConfig()
|
|
|
|
|
|
2024-04-22 23:08:40 +08:00
|
|
|
|
// 插件模块,切换到插件下运行gen service
|
2023-02-23 17:53:04 +08:00
|
|
|
|
if genConfig.Application.Crud.Templates[pin.GenTemplate].IsAddon {
|
|
|
|
|
// 依然使用配置中的参数,只是将生成路径指向插件模块路径
|
|
|
|
|
cfg.SrcFolder = "addons/" + pin.AddonName + "/logic"
|
|
|
|
|
cfg.DstFolder = "addons/" + pin.AddonName + "/service"
|
|
|
|
|
}
|
2024-04-22 23:08:40 +08:00
|
|
|
|
err = ServiceWithCfg(ctx, cfg)
|
2023-02-23 17:53:04 +08:00
|
|
|
|
return
|
|
|
|
|
}},
|
2023-01-18 16:23:39 +08:00
|
|
|
|
})
|
|
|
|
|
case consts.GenCodesTypeQueue:
|
|
|
|
|
err = gerror.Newf("生成类型开发中!")
|
|
|
|
|
return
|
|
|
|
|
default:
|
|
|
|
|
err = gerror.Newf("生成类型暂不支持!")
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|