版本预发布

This commit is contained in:
孟帅
2023-02-08 20:29:34 +08:00
parent f11c7c5bf2
commit 2068d05c93
269 changed files with 16122 additions and 12075 deletions

View File

@@ -15,6 +15,7 @@ import (
"hotgo/internal/library/hggen/internal/cmd"
"hotgo/internal/library/hggen/internal/cmd/gendao"
"hotgo/internal/library/hggen/views"
"hotgo/internal/model"
"hotgo/internal/model/input/form"
"hotgo/internal/model/input/sysin"
"hotgo/internal/service"
@@ -49,11 +50,33 @@ func TableColumns(ctx context.Context, in sysin.GenCodesColumnListInp) (fields [
func TableSelects(ctx context.Context, in sysin.GenCodesSelectsInp) (res *sysin.GenCodesSelectsModel, err error) {
res = new(sysin.GenCodesSelectsModel)
for k, v := range consts.GenCodesTypeNameMap {
res.GenType = append(res.GenType, &form.Select{
Value: k,
Name: v,
Label: v,
})
row := &sysin.GenTypeSelect{
Value: k,
Name: v,
Label: v,
Templates: make(form.Selects, 0),
}
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 {
row.Templates = append(row.Templates, &form.Select{
Value: index,
Label: temp.Group,
Name: temp.Group,
})
}
sort.Sort(row.Templates)
}
}
res.GenType = append(res.GenType, row)
}
sort.Sort(res.GenType)
res.Db = DbSelect(ctx)

View File

@@ -61,7 +61,6 @@ func GetServiceConfig() genservice.CGenServiceInput {
}
func GetDaoConfig(group string) gendao.CGenDaoInput {
inp := defaultGenDaoInput
find := func(group string) g.Map {
for _, v := range daoConfig {
if v.(g.Map)["group"].(string) == group {
@@ -72,9 +71,9 @@ func GetDaoConfig(group string) gendao.CGenDaoInput {
}
v := find(group)
inp := defaultGenDaoInput
if v != nil {
err := gconv.Scan(v, &inp)
if err != nil {
if err := gconv.Scan(v, &inp); err != nil {
panic(err)
}
}

View File

@@ -10,7 +10,7 @@ var (
)
type cGen struct {
g.Meta `name:"hggen" brief:"{cGenBrief}" dc:"{cGenDc}"`
g.Meta `name:"gen" brief:"{cGenBrief}" dc:"{cGenDc}"`
cGenDao
cGenPb
cGenPbEntity
@@ -20,9 +20,9 @@ type cGen struct {
const (
cGenBrief = `automatically generate go files for dao/do/entity/pb/pbentity`
cGenDc = `
The "hggen" command is designed for multiple generating purposes.
The "gen" command is designed for multiple generating purposes.
It's currently supporting generating go files for ORM models, protobuf and protobuf entity files.
Please use "gf hggen dao -h" for specified type help.
Please use "gf gen dao -h" for specified type help.
`
)

View File

@@ -44,22 +44,22 @@ type (
)
const (
cGenPbEntityConfig = `gfcli.hggen.pbentity`
cGenPbEntityConfig = `gfcli.gen.pbentity`
cGenPbEntityBrief = `generate entity message files in protobuf3 format`
cGenPbEntityEg = `
gf hggen pbentity
gf hggen pbentity -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
gf hggen pbentity -p ./protocol/demos/entity -t user,user_detail,user_login
gf hggen pbentity -r user_
gf gen pbentity
gf gen pbentity -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
gf gen pbentity -p ./protocol/demos/entity -t user,user_detail,user_login
gf gen pbentity -r user_
`
cGenPbEntityAd = `
CONFIGURATION SUPPORT
Options are also supported by configuration file.
It's suggested using configuration file instead of command line arguments making producing.
The configuration node name is "gf.hggen.pbentity", which also supports multiple databases, for example(config.yaml):
The configuration node name is "gf.gen.pbentity", which also supports multiple databases, for example(config.yaml):
gfcli:
hggen:
gen:
- pbentity:
link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
path: "protocol/demos/entity"

View File

@@ -18,23 +18,23 @@ import (
)
const (
CGenDaoConfig = `gfcli.hggen.dao`
CGenDaoUsage = `gf hggen dao [OPTION]`
CGenDaoConfig = `gfcli.gen.dao`
CGenDaoUsage = `gf gen dao [OPTION]`
CGenDaoBrief = `automatically generate go files for dao/do/entity`
CGenDaoEg = `
gf hggen dao
gf hggen dao -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
gf hggen dao -p ./model -g user-center -t user,user_detail,user_login
gf hggen dao -r user_
gf gen dao
gf gen dao -l "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
gf gen dao -p ./model -g user-center -t user,user_detail,user_login
gf gen dao -r user_
`
CGenDaoAd = `
CONFIGURATION SUPPORT
Options are also supported by configuration file.
It's suggested using configuration file instead of command line arguments making producing.
The configuration node name is "gfcli.hggen.dao", which also supports multiple databases, for example(config.yaml):
The configuration node name is "gfcli.gen.dao", which also supports multiple databases, for example(config.yaml):
gfcli:
hggen:
gen:
dao:
- link: "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
tables: "order,products"
@@ -179,7 +179,6 @@ type (
)
func (c CGenDao) Dao(ctx context.Context, in CGenDaoInput) (out *CGenDaoOutput, err error) {
g.Log().Warningf(ctx, "g.Cfg().Available(ctx):%v", g.Cfg().Available(ctx))
if g.Cfg().Available(ctx) {
v := g.Cfg().MustGet(ctx, CGenDaoConfig)
if v.IsSlice() {
@@ -200,7 +199,7 @@ func DoGenDaoForArray(ctx context.Context, in CGenDaoInput) {
doGenDaoForArray(ctx, -1, in)
}
// doGenDaoForArray implements the "hggen dao" command for configuration array.
// doGenDaoForArray implements the "gen dao" command for configuration array.
func doGenDaoForArray(ctx context.Context, index int, in CGenDaoInput) {
var (
err error

View File

@@ -20,12 +20,12 @@ import (
)
const (
CGenServiceConfig = `gfcli.hggen.service`
CGenServiceUsage = `gf hggen service [OPTION]`
CGenServiceConfig = `gfcli.gen.service`
CGenServiceUsage = `gf gen service [OPTION]`
CGenServiceBrief = `parse struct and associated functions from packages to generate service go file`
CGenServiceEg = `
gf hggen service
gf hggen service -f Snake
gf gen service
gf gen service -f Snake
`
CGenServiceBriefSrcFolder = `source folder path to be parsed. default: internal/logic`
CGenServiceBriefDstFolder = `destination folder path storing automatically generated go files. default: internal/service`
@@ -89,13 +89,13 @@ const (
func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGenServiceOutput, err error) {
// File lock to avoid multiple processes.
var (
flockFilePath = gfile.Temp("gf.cli.hggen.service.lock")
flockFilePath = gfile.Temp("gf.cli.gen.service.lock")
flockContent = gfile.GetContents(flockFilePath)
)
if flockContent != "" {
if gtime.Timestamp()-gconv.Int64(flockContent) < genServiceFileLockSeconds {
// If another "hggen service" process is running, it just exits.
mlog.Debug(`another "hggen service" process is running, exit`)
// If another "gen service" process is running, it just exits.
mlog.Debug(`another "gen service" process is running, exit`)
return
}
}
@@ -127,7 +127,7 @@ func (c CGenService) Service(ctx context.Context, in CGenServiceInput) (out *CGe
mlog.Debug("Chdir:", newWorkingDir)
_ = gfile.Remove(flockFilePath)
var command = fmt.Sprintf(
`%s hggen service -packages=%s`,
`%s gen service -packages=%s`,
gfile.SelfName(), gfile.Basename(watchFileDir),
)
err = gproc.ShellRun(ctx, command)

View File

@@ -157,6 +157,11 @@ func setDefaultFormMode(field *sysin.GenCodesColumnListModel) {
return
}
if (field.GoName == "ProvinceId" || field.GoName == "CityId") && IsNumberType(field.GoType) {
field.FormMode = FormModeCitySelector
return
}
if field.DataType == "datetime" || field.DataType == "timestamp" || field.DataType == "timestamptz" {
field.FormMode = FormModeTime
return

View File

@@ -115,6 +115,7 @@ const (
FormModeUploadFiles = "UploadFiles" // 多文件上传
FormModeSwitch = "Switch" // 开关
FormModeRate = "Rate" // 评分
FormModeCitySelector = "CitySelector" // 省市区选择
)
var FormModes = []string{
@@ -124,6 +125,7 @@ var FormModes = []string{
FormModeUploadImage, FormModeUploadImages, FormModeUploadFile, FormModeUploadFiles,
FormModeSwitch,
FormModeRate,
FormModeCitySelector,
}
var FormModeMap = map[string]string{
@@ -146,6 +148,7 @@ var FormModeMap = map[string]string{
FormModeUploadFiles: "多文件上传",
FormModeSwitch: "开关",
FormModeRate: "评分",
FormModeCitySelector: "省市区选择",
}
// 表单验证

View File

@@ -118,7 +118,16 @@ func (l *gCurd) initInput(ctx context.Context, in *CurdPreviewInput) (err error)
initStep(ctx, in)
in.options.dictMap = make(g.Map)
in.options.TemplateGroup = "sys"
if len(in.Config.Application.Crud.Templates)-1 < in.In.GenTemplate {
return gerror.New("没有找到生成模板的配置,请检查!")
}
err = checkCurdPath(in.Config.Application.Crud.Templates[in.In.GenTemplate])
if err != nil {
return
}
in.options.TemplateGroup = in.Config.Application.Crud.Templates[in.In.GenTemplate].MasterPackage
return
}
@@ -137,14 +146,14 @@ func initStep(ctx context.Context, in *CurdPreviewInput) {
in.options.Step.HasMenu = gstr.InArray(in.options.AutoOps, "genMenuPermissions")
}
func (l *gCurd) loadView(ctx context.Context, in *CurdPreviewInput) error {
func (l *gCurd) loadView(ctx context.Context, in *CurdPreviewInput) (err error) {
view := gview.New()
err := view.SetConfigWithMap(g.Map{
"Paths": "./resource/template/generate/default/curd",
err = view.SetConfigWithMap(g.Map{
"Paths": in.Config.Application.Crud.Templates[in.In.GenTemplate].TemplatePath,
"Delimiters": in.Config.Delimiters,
})
if err != nil {
return err
return
}
view.BindFuncMap(g.Map{
@@ -156,7 +165,7 @@ func (l *gCurd) loadView(ctx context.Context, in *CurdPreviewInput) error {
dictOptions, err := l.generateWebModelDictOptions(ctx, in)
if err != nil {
return err
return
}
view.Assigns(gview.Params{
@@ -174,13 +183,13 @@ func (l *gCurd) loadView(ctx context.Context, in *CurdPreviewInput) error {
"dictOptions": dictOptions, // web字典选项
})
in.view = view
return nil
return
}
func (l *gCurd) DoBuild(ctx context.Context, in *CurdBuildInput) (err error) {
preview, err := l.DoPreview(ctx, in.PreviewIn)
if err != nil {
return err
return
}
// 前置操作
@@ -307,7 +316,7 @@ func (l *gCurd) generateApiContent(ctx context.Context, in *CurdPreviewInput) (e
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].ApiPath, strings.ToLower(in.In.VarName), strings.ToLower(in.In.VarName)+".go")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].ApiPath, strings.ToLower(in.In.VarName), strings.ToLower(in.In.VarName)+".go")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -338,7 +347,7 @@ func (l *gCurd) generateInputContent(ctx context.Context, in *CurdPreviewInput)
if err != nil {
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].InputPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].InputPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -364,7 +373,7 @@ func (l *gCurd) generateControllerContent(ctx context.Context, in *CurdPreviewIn
if err != nil {
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].ControllerPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].ControllerPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -394,7 +403,7 @@ func (l *gCurd) generateLogicContent(ctx context.Context, in *CurdPreviewInput)
if err != nil {
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].LogicPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].LogicPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -420,7 +429,7 @@ func (l *gCurd) generateRouterContent(ctx context.Context, in *CurdPreviewInput)
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].RouterPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].RouterPath, convert.CamelCaseToUnderline(in.In.VarName)+".go")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -446,7 +455,7 @@ func (l *gCurd) generateWebApiContent(ctx context.Context, in *CurdPreviewInput)
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].WebApiPath, gstr.LcFirst(in.In.VarName), "index.ts")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].WebApiPath, gstr.LcFirst(in.In.VarName), "index.ts")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -477,7 +486,7 @@ func (l *gCurd) generateWebModelContent(ctx context.Context, in *CurdPreviewInpu
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].WebViewsPath, gstr.LcFirst(in.In.VarName), "model.ts")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].WebViewsPath, gstr.LcFirst(in.In.VarName), "model.ts")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -507,7 +516,7 @@ func (l *gCurd) generateWebIndexContent(ctx context.Context, in *CurdPreviewInpu
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].WebViewsPath, gstr.LcFirst(in.In.VarName), "index.vue")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].WebViewsPath, gstr.LcFirst(in.In.VarName), "index.vue")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -538,7 +547,7 @@ func (l *gCurd) generateWebEditContent(ctx context.Context, in *CurdPreviewInput
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].WebViewsPath, gstr.LcFirst(in.In.VarName), "edit.vue")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].WebViewsPath, gstr.LcFirst(in.In.VarName), "edit.vue")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -573,7 +582,7 @@ func (l *gCurd) generateWebViewContent(ctx context.Context, in *CurdPreviewInput
return err
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].WebViewsPath, gstr.LcFirst(in.In.VarName), "view.vue")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].WebViewsPath, gstr.LcFirst(in.In.VarName), "view.vue")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip
@@ -609,7 +618,7 @@ func (l *gCurd) generateSqlContent(ctx context.Context, in *CurdPreviewInput) (e
tplData["mainComponent"] = "ParentLayout" //gstr.LcFirst(in.In.VarName)
}
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[0].SqlPath, convert.CamelCaseToUnderline(in.In.VarName)+"_menu.sql")
genFile.Path = file.MergeAbs(in.Config.Application.Crud.Templates[in.In.GenTemplate].SqlPath, convert.CamelCaseToUnderline(in.In.VarName)+"_menu.sql")
genFile.Meth = consts.GenCodesBuildMethCreate
if gfile.Exists(genFile.Path) {
genFile.Meth = consts.GenCodesBuildMethSkip

View File

@@ -19,11 +19,13 @@ import (
const (
LogicWhereComments = "\n\t// 查询%s\n"
LogicWhereNoSupport = "\t// TODO 暂不支持生成[ %s ]查询方式,请自行补充此处代码!"
LogicListSimpleSelect = "\tfields, err := hgorm.GenSelect(ctx, sysin.%sListModel{}, dao.%s)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}"
LogicListSimpleSelect = "\tfields, err := hgorm.GenSelect(ctx, sysin.%sListModel{}, dao.%s)\n\tif err != nil {\n\t\treturn\n\t}"
LogicListJoinSelect = "\t//关联表select\n\tfields, err := hgorm.GenJoinSelect(ctx, %sin.%sListModel{}, dao.%s, []*hgorm.Join{\n%v\t})"
LogicListJoinOnRelation = "\t// 关联表%s\n\tmod = mod.%s(hgorm.GenJoinOnRelation(\n\t\tdao.%s.Table(), dao.%s.Columns().%s, // 主表表名,关联条件\n\t\tdao.%s.Table(), \"%s\", dao.%s.Columns().%s, // 关联表表名,别名,关联条件\n\t)...)\n\n"
LogicEditUpdate = "\t\t_, err = dao.%s.Ctx(ctx).\n\t\t\tFieldsEx(\n%s\t\t\t).\n\t\t\tWhere(dao.%s.Columns().%s, in.%s).Data(in).Update()\n\t\tif err != nil {\n\t\t\terr = gerror.Wrap(err, consts.ErrorORM)\n\t\t\treturn err\n\t\t}\n\t\treturn nil"
LogicEditInsert = "\t_, err = dao.%s.Ctx(ctx).\n\t\tFieldsEx(\n%s\t\t).\n\t\tData(in).Insert()\n\tif err != nil {\n\t\terr = gerror.Wrap(err, consts.ErrorORM)\n\t\treturn err\n\t}"
LogicEditUpdate = "\t\t_, err = s.Model(ctx).\n\t\t\tFieldsEx(\n%s\t\t\t).\n\t\t\tWhere(dao.%s.Columns().%s, in.%s).Data(in).Update()\n\t\treturn "
LogicEditInsert = "\t_, err = s.Model(ctx, &handler.Option{FilterAuth: false}).\n\t\tFieldsEx(\n%s\t\t).\n\t\tData(in).Insert()"
LogicSwitchUpdate = "g.Map{\n\t\tin.Key: in.Value,\n%s}"
LogicStatusUpdate = "g.Map{\n\t\tdao.%s.Columns().Status: in.Status,\n%s}"
)
func (l *gCurd) logicTplData(ctx context.Context, in *CurdPreviewInput) (data g.Map, err error) {
@@ -33,9 +35,35 @@ func (l *gCurd) logicTplData(ctx context.Context, in *CurdPreviewInput) (data g.
data["listOrder"] = l.generateLogicListOrder(ctx, in)
data["edit"] = l.generateLogicEdit(ctx, in)
data["switchFields"] = l.generateLogicSwitchFields(ctx, in)
data["switchUpdate"] = l.generateLogicSwitchUpdate(ctx, in)
data["statusUpdate"] = l.generateLogicStatusUpdate(ctx, in)
return
}
func (l *gCurd) generateLogicStatusUpdate(ctx context.Context, in *CurdPreviewInput) string {
var update string
for _, field := range in.masterFields {
if field.GoName == "UpdatedBy" {
update += "\t\tdao." + in.In.DaoName + ".Columns().UpdatedBy: contexts.GetUserId(ctx),\n"
}
}
update += "\t"
return fmt.Sprintf(LogicStatusUpdate, in.In.DaoName, update)
}
func (l *gCurd) generateLogicSwitchUpdate(ctx context.Context, in *CurdPreviewInput) string {
var update string
for _, field := range in.masterFields {
if field.GoName == "UpdatedBy" {
update += "\t\tdao." + in.In.DaoName + ".Columns().UpdatedBy: contexts.GetUserId(ctx),\n"
}
}
update += "\t"
return fmt.Sprintf(LogicSwitchUpdate, update)
}
func (l *gCurd) generateLogicSwitchFields(ctx context.Context, in *CurdPreviewInput) string {
buffer := bytes.NewBuffer(nil)
if in.options.Step.HasSwitch {
@@ -71,8 +99,8 @@ func (l *gCurd) generateLogicEdit(ctx context.Context, in *CurdPreviewInput) g.M
}
}
updateBuffer.WriteString(fmt.Sprintf(LogicEditUpdate, in.In.DaoName, updateFieldsEx, in.In.DaoName, in.pk.GoName, in.pk.GoName))
insertBuffer.WriteString(fmt.Sprintf(LogicEditInsert, in.In.DaoName, insertFieldsEx))
updateBuffer.WriteString(fmt.Sprintf(LogicEditUpdate, updateFieldsEx, in.In.DaoName, in.pk.GoName, in.pk.GoName))
insertBuffer.WriteString(fmt.Sprintf(LogicEditInsert, insertFieldsEx))
data["update"] = updateBuffer.String()
data["insert"] = insertBuffer.String()

View File

@@ -34,7 +34,7 @@ func (l *gCurd) generateWebEditFormItem(ctx context.Context, in *CurdPreviewInpu
}
var (
defaultComponent = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-input placeholder=\"请输入%s\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.Dc, field.TsName)
defaultComponent = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-input placeholder=\"请输入%s\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.Dc, field.TsName)
component string
)
@@ -43,65 +43,68 @@ func (l *gCurd) generateWebEditFormItem(ctx context.Context, in *CurdPreviewInpu
component = defaultComponent
case FormModeInputNumber:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-input-number placeholder=\"请输入%s\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.Dc, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-input-number placeholder=\"请输入%s\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.Dc, field.TsName)
case FormModeInputTextarea:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-input type=\"textarea\" placeholder=\"%s\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.Dc, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-input type=\"textarea\" placeholder=\"%s\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.Dc, field.TsName)
case FormModeInputEditor:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <Editor style=\"height: 450px\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <Editor style=\"height: 450px\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
case FormModeInputDynamic:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-dynamic-input\n v-model:value=\"params.%s\"\n preset=\"pair\"\n key-placeholder=\"键名\"\n value-placeholder=\"键值\"\n />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-dynamic-input\n v-model:value=\"params.%s\"\n preset=\"pair\"\n key-placeholder=\"键名\"\n value-placeholder=\"键值\"\n />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
case FormModeDate:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <DatePicker v-model:formValue=\"params.%s\" type=\"date\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <DatePicker v-model:formValue=\"params.%s\" type=\"date\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
//case FormModeDateRange: // 必须要有两个字段,后面优化下
case FormModeTime:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <DatePicker v-model:formValue=\"params.%s\" type=\"datetime\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <DatePicker v-model:formValue=\"params.%s\" type=\"datetime\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
//case FormModeTimeRange: // 必须要有两个字段,后面优化下
case FormModeRadio:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-radio-group v-model:value=\"params.%s\" name=\"%s\">\n <n-radio-button\n v-for=\"%s in options.%s\"\n :key=\"%s.value\"\n :value=\"%s.value\"\n :label=\"%s.label\"\n />\n </n-radio-group>\n </n-form-item>", field.Dc, field.TsName, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], field.TsName, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-radio-group v-model:value=\"params.%s\" name=\"%s\">\n <n-radio-button\n v-for=\"%s in options.%s\"\n :key=\"%s.value\"\n :value=\"%s.value\"\n :label=\"%s.label\"\n />\n </n-radio-group>\n </n-form-item>", field.Dc, field.TsName, field.TsName, field.TsName, field.TsName, in.options.dictMap[field.TsName], field.TsName, field.TsName, field.TsName)
case FormModeCheckbox:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-checkbox-group v-model:value=\"params.%s\">\n <n-space>\n <n-checkbox\n v-for=\"item in options.%s\"\n :key=\"item.value\"\n :value=\"item.value\"\n :label=\"item.label\"\n />\n </n-space>\n </n-checkbox-group>\n </n-form-item>", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName])
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-checkbox-group v-model:value=\"params.%s\">\n <n-space>\n <n-checkbox\n v-for=\"item in options.%s\"\n :key=\"item.value\"\n :value=\"item.value\"\n :label=\"item.label\"\n />\n </n-space>\n </n-checkbox-group>\n </n-form-item>", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName])
case FormModeSelect:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-select v-model:value=\"params.%s\" :options=\"options.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName])
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-select v-model:value=\"params.%s\" :options=\"options.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName])
case FormModeSelectMultiple:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-select multiple v-model:value=\"params.%s\" :options=\"options.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName])
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-select multiple v-model:value=\"params.%s\" :options=\"options.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName, in.options.dictMap[field.TsName])
case FormModeUploadImage:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadImage :maxNumber=\"1\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadImage :maxNumber=\"1\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
case FormModeUploadImages:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadImage :maxNumber=\"10\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadImage :maxNumber=\"10\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
case FormModeUploadFile:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadFile :maxNumber=\"1\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadFile :maxNumber=\"1\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
case FormModeUploadFiles:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadFile :maxNumber=\"10\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <UploadFile :maxNumber=\"10\" v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
case FormModeSwitch:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-switch v-model:value=\"params.%s\"\n />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-switch :unchecked-value=\"2\" :checked-value=\"1\" v-model:value=\"params.%s\"\n />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
case FormModeRate:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-rate allow-half :default-value=\"params.%s\" :on-update:value=\"update%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName, field.GoName)
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <n-rate allow-half :default-value=\"params.%s\" :on-update:value=\"update%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName, field.GoName)
case FormModeCitySelector:
component = fmt.Sprintf("<n-form-item label=\"%s\" path=\"%s\">\n <CitySelector v-model:value=\"params.%s\" />\n </n-form-item>", field.Dc, field.TsName, field.TsName)
default:
component = defaultComponent
}
if len(in.masterFields) == k {
buffer.WriteString(" " + component)
buffer.WriteString(" " + component)
} else {
buffer.WriteString(" " + component + "\n\n")
buffer.WriteString(" " + component + "\n\n")
}
}
@@ -117,11 +120,12 @@ func (l *gCurd) generateWebEditScript(ctx context.Context, in *CurdPreviewInput)
if in.options.Step.HasMaxSort {
importBuffer.WriteString(" import { onMounted, ref, computed, watch } from 'vue';\n")
importBuffer.WriteString(" import { Edit, MaxSort } from '@/api/" + gstr.LcFirst(in.In.VarName) + "';\n")
setupBuffer.WriteString(" watch(\n () => params.value,\n (value) => {\n if (value.id === 0) {\n MaxSort().then((res) => {\n params.value.sort = res.sort;\n });\n }\n }\n );\n\n")
importBuffer.WriteString(" import { Edit, MaxSort, View } from '@/api/" + gstr.LcFirst(in.In.VarName) + "';\n")
setupBuffer.WriteString(" function loadForm(value) {\n loading.value = true;\n\n // 新增\n if (value.id < 1) {\n params.value = newState(value);\n MaxSort()\n .then((res) => {\n params.value.sort = res.sort;\n })\n .finally(() => {\n loading.value = false;\n });\n return;\n }\n\n // 编辑\n View({ id: value.id })\n .then((res) => {\n params.value = res;\n })\n .finally(() => {\n loading.value = false;\n });\n }\n\n watch(\n () => props.formParams,\n (value) => {\n loadForm(value);\n }\n );")
} else {
importBuffer.WriteString(" import { onMounted, ref, computed } from 'vue';\n")
importBuffer.WriteString(" import { Edit } from '@/api/" + gstr.LcFirst(in.In.VarName) + "';\n")
importBuffer.WriteString(" import { Edit, View } from '@/api/" + gstr.LcFirst(in.In.VarName) + "';\n")
setupBuffer.WriteString(" function loadForm(value) {\n // 新增\n if (value.id < 1) {\n params.value = newState(value);\n loading.value = false;\n return;\n }\n\n loading.value = true;\n // 编辑\n View({ id: value.id })\n .then((res) => {\n params.value = res;\n })\n .finally(() => {\n loading.value = false;\n });\n }\n\n watch(\n () => props.formParams,\n (value) => {\n loadForm(value);\n }\n );")
}
for _, field := range in.masterFields {
@@ -147,12 +151,15 @@ func (l *gCurd) generateWebEditScript(ctx context.Context, in *CurdPreviewInput)
}
case FormModeRate:
setupBuffer.WriteString(fmt.Sprintf(" function update%s(num) {\n params.value.%s = num;\n }\n", field.GoName, field.TsName))
case FormModeCitySelector:
if !gstr.Contains(importBuffer.String(), `import CitySelector`) {
importBuffer.WriteString(" import CitySelector from '@/components/CitySelector/citySelector.vue';\n")
}
}
}
data["import"] = importBuffer.String()
data["setup"] = setupBuffer.String()
return data
}

View File

@@ -1,4 +1,4 @@
// Package hggen
// Package views
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2022 HotGo CLI
// @Author Ms <133814250@qq.com>
@@ -8,9 +8,12 @@ package views
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gfile"
"github.com/gogf/gf/v2/text/gstr"
"hotgo/internal/consts"
"hotgo/internal/model"
"hotgo/internal/model/input/sysin"
"io/ioutil"
"strings"
@@ -94,3 +97,41 @@ func ImportSql(ctx context.Context, path string) error {
return nil
}
func checkCurdPath(temp *model.GenerateAppCrudTemplate) (err error) {
if temp == nil {
return gerror.New("生成模板配置不能为空")
}
tip := `生成模板配置参数'%s'路径不存在,请先创建路径`
if !gfile.Exists(temp.TemplatePath) {
return gerror.Newf(tip, "TemplatePath")
}
if !gfile.Exists(temp.ApiPath) {
return gerror.Newf(tip, "ApiPath")
}
if !gfile.Exists(temp.InputPath) {
return gerror.Newf(tip, "InputPath")
}
if !gfile.Exists(temp.ControllerPath) {
return gerror.Newf(tip, "ControllerPath")
}
if !gfile.Exists(temp.LogicPath) {
return gerror.Newf(tip, "LogicPath")
}
if !gfile.Exists(temp.RouterPath) {
return gerror.Newf(tip, "RouterPath")
}
if !gfile.Exists(temp.SqlPath) {
return gerror.Newf(tip, "SqlPath")
}
if !gfile.Exists(temp.WebApiPath) {
return gerror.Newf(tip, "WebApiPath")
}
if !gfile.Exists(temp.WebViewsPath) {
return gerror.Newf(tip, "WebViewsPath")
}
return
}