package tools import ( "IotAdmin/app/system/models" "IotAdmin/app/system/service" "IotAdmin/common/global" "bytes" "fmt" "strconv" "strings" "text/template" "time" "IotAdmin/core/sdk/api" "IotAdmin/core/sdk/config" "IotAdmin/core/sdk/pkg" "github.com/gin-gonic/gin" "gorm.io/gorm" "IotAdmin/app/other/models/tools" ) type Gen struct { api.Api } // Preview 生成预览 // @Summary 生成预览 // @Description 生成预览 // @Tags 系統接口 / 生成工具 / 生成代码 // @Param tableId path string false "tableId / 表Id" // @Success 200 {object} response.Response "{"code": 200, "data": [...]}" // @Router /api/sys/gen-preview/{tableId} [get] func (e Gen) Preview(c *gin.Context) { e.Context = c log := e.GetLogger() table := tools.SysTables{} id, err := pkg.StringToInt(c.Param("tableId")) if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("tableId接收失败!错误详情:%s", err.Error())) return } table.TableId = id tModel, err := template.ParseFiles("template/v4/model.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("model模版读取失败!错误详情:%s", err.Error())) return } tApis, err := template.ParseFiles("template/v4/no_actions/apis.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("api模版读取失败!错误详情:%s", err.Error())) return } tVueApi, err := template.ParseFiles("template/v4/vue-api.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("vue-api-ts模版读取失败!错误详情:%s", err.Error())) return } tVueView, err := template.ParseFiles("template/v4/vue-view.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("vue-view模版读取失败!错误详情:%s", err.Error())) return } tRouter, err := template.ParseFiles("template/v4/no_actions/router_check_role.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("路由模版读取失败!错误详情:%s", err.Error())) return } tDto, err := template.ParseFiles("template/v4/dto.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("dto模版读取失败!错误详情:%s", err.Error())) return } tService, err := template.ParseFiles("template/v4/no_actions/service.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("service模版读取失败!错误详情:%s", err.Error())) return } db, err := pkg.GetOrm(c) if err != nil { log.Errorf("get db connection error, %s", err.Error()) e.Error(500, err, fmt.Sprintf("数据库链接获取失败!错误详情:%s", err.Error())) return } tab, _ := table.Get(db, false) var ( bVueApi bytes.Buffer bVueView bytes.Buffer bModel bytes.Buffer bApis bytes.Buffer bRouter bytes.Buffer bDto bytes.Buffer bService bytes.Buffer ) err = tModel.Execute(&bModel, tab) err = tApis.Execute(&bApis, tab) err = tVueApi.Execute(&bVueApi, tab) err = tVueView.Execute(&bVueView, tab) err = tRouter.Execute(&bRouter, tab) err = tDto.Execute(&bDto, tab) err = tService.Execute(&bService, tab) mp := make(map[string]interface{}) mp["template/vue-api.go.template"] = bVueApi.String() mp["template/vue-view.go.template"] = bVueView.String() mp["template/model.go.template"] = bModel.String() mp["template/api.go.template"] = bApis.String() mp["template/router.go.template"] = bRouter.String() mp["template/dto.go.template"] = bDto.String() mp["template/service.go.template"] = bService.String() e.OK(mp, "") } // GenCode 生成代码 // @Summary 生成代码 // @Description 生成代码 // @Tags 系統接口 / 生成工具 / 生成代码 // @Param tableId path string false "tableId / 表Id" // @Success 200 {object} response.Response "{"code": 200, "data": [...]}" // @Router /api/sys/gen-code/{tableId} [get] func (e Gen) GenCode(c *gin.Context) { e.Context = c log := e.GetLogger() table := tools.SysTables{} id, err := pkg.StringToInt(c.Param("tableId")) if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("tableId参数接收失败!错误详情:%s", err.Error())) return } db, err := pkg.GetOrm(c) if err != nil { log.Errorf("get db connection error, %s", err.Error()) e.Error(500, err, fmt.Sprintf("数据库链接获取失败!错误详情:%s", err.Error())) return } table.TableId = id tab, _ := table.Get(db, false) e.NOActionsGen(c, tab) e.OK("", "Code generated successfully!") } // GenApiToFile 生成 Menu 迁移文件 (弃用) // @Summary 生成 Menu 迁移文件 // @Description 生成 Menu 迁移文件 // @Tags 系統接口 / 生成工具 / 生成代码 // @Param tableId path string false "tableId / 表Id" // @Success 200 {object} response.Response "{"code": 200, "data": [...]}" // @Router /api/sys/gen-api-to-file/{tableId} [get] func (e Gen) GenApiToFile(c *gin.Context) { e.Context = c log := e.GetLogger() table := tools.SysTables{} id, err := pkg.StringToInt(c.Param("tableId")) if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("tableId参数获取失败!错误详情:%s", err.Error())) return } db, err := pkg.GetOrm(c) if err != nil { log.Errorf("get db connection error, %s", err.Error()) e.Error(500, err, fmt.Sprintf("数据库链接获取失败!错误详情:%s", err.Error())) return } table.TableId = id tab, _ := table.Get(db, false) e.genApiToFile(c, tab) e.OK("", "Code generated successfully!") } func (e Gen) NOActionsGen(c *gin.Context, tab tools.SysTables) { e.Context = c log := e.GetLogger() tab.MLTBName = strings.Replace(tab.TBName, "_", "-", -1) basePath := "template/v4/" routerFile := basePath + "no_actions/router_check_role.go.template" if tab.IsAuth == 2 { routerFile = basePath + "no_actions/router_no_check_role.go.template" } model, err := template.ParseFiles(basePath + "model.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("model模版读取失败!错误详情:%s", err.Error())) return } apis, err := template.ParseFiles(basePath + "no_actions/apis.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("api模版读取失败!错误详情:%s", err.Error())) return } router, err := template.ParseFiles(routerFile) if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("路由模版失败!错误详情:%s", err.Error())) return } sDto, err := template.ParseFiles(basePath + "dto.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("dto模版解析失败失败!错误详情:%s", err.Error())) return } sService, err := template.ParseFiles(basePath + "no_actions/service.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("service模版失败!错误详情:%s", err.Error())) return } vueApi, err := template.ParseFiles(basePath + "vue-api.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("vue-api模版解析失败!错误详情:%s", err.Error())) return } vueView, err := template.ParseFiles(basePath + "vue-view.go.template") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("vue-view模版解析失败!错误详情:%s", err.Error())) return } _ = pkg.PathCreate("./app/" + tab.PackageName + "/apis/") _ = pkg.PathCreate("./app/" + tab.PackageName + "/models/") _ = pkg.PathCreate("./app/" + tab.PackageName + "/router/") _ = pkg.PathCreate("./app/" + tab.PackageName + "/service/dto/") _ = pkg.PathCreate(config.GenConfig.FrontPath + "/api/" + tab.PackageName + "/") err = pkg.PathCreate(config.GenConfig.FrontPath + "/views/" + tab.PackageName + "/" + tab.BusinessName + "/") if err != nil { log.Error(err) e.Error(500, err, fmt.Sprintf("views目录创建失败!错误详情:%s", err.Error())) return } var bModel bytes.Buffer err = model.Execute(&bModel, tab) var bApis bytes.Buffer err = apis.Execute(&bApis, tab) var bRouter bytes.Buffer err = router.Execute(&bRouter, tab) var bDto bytes.Buffer err = sDto.Execute(&bDto, tab) var bService bytes.Buffer var bVueApi bytes.Buffer err = vueApi.Execute(&bVueApi, tab) var bVueView bytes.Buffer err = vueView.Execute(&bVueView, tab) err = sService.Execute(&bService, tab) pkg.FileCreate(bModel, "./app/"+tab.PackageName+"/models/"+tab.BusinessName+".go") pkg.FileCreate(bApis, "./app/"+tab.PackageName+"/apis/"+tab.BusinessName+".go") pkg.FileCreate(bRouter, "./app/"+tab.PackageName+"/router/"+tab.BusinessName+".go") pkg.FileCreate(bDto, "./app/"+tab.PackageName+"/service/dto/"+tab.BusinessName+".go") pkg.FileCreate(bService, "./app/"+tab.PackageName+"/service/"+tab.BusinessName+".go") pkg.FileCreate(bVueApi, config.GenConfig.FrontPath+"/api/"+tab.PackageName+"/_"+tab.BusinessName+".ts") pkg.FileCreate(bVueView, config.GenConfig.FrontPath+"/views/"+tab.PackageName+"/"+tab.BusinessName+"/index.vue") } func (e Gen) genApiToFile(c *gin.Context, tab tools.SysTables) { err := e.MakeContext(c). MakeOrm(). Errors if err != nil { e.Logger.Error(err) e.Error(500, err, err.Error()) return } basePath := "template/" t1, err := template.ParseFiles(basePath + "api_migrate.template") if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("数据迁移模版解析失败!错误详情:%s", err.Error())) return } i := strconv.FormatInt(time.Now().UnixNano()/1e6, 10) var b1 bytes.Buffer err = t1.Execute(&b1, struct { tools.SysTables GenerateTime string }{tab, i}) pkg.FileCreate(b1, "./cmd/migrate/migration/version-local/"+i+"_migrate.go") } // GenMenuAndApi 生成菜单API到DB // @Summary 生成菜单及接口 // @Description 生成菜单API到DB // @Tags 系統接口 / 生成工具 / 生成代码 // @Param tableId path string false "tableId / 表Id" // @Success 200 {object} response.Response "{"code": 200, "data": [...]}" // @Router /api/sys/gen-menu-api/{tableId} [get] func (e Gen) GenMenuAndApi(c *gin.Context) { s := service.SysMenuService{} err := e.MakeContext(c). MakeOrm(). MakeService(&s.Service). Errors if err != nil { e.Logger.Error(err) e.Error(500, err, err.Error()) return } table := tools.SysTables{} id, err := pkg.StringToInt(c.Param("tableId")) if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("tableId参数解析失败!错误详情:%s", err.Error())) return } table.TableId = id tab, _ := table.Get(e.Orm, true) tab.MLTBName = strings.Replace(tab.TBName, "_", "-", -1) tx := e.Orm.Debug().Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() menu, err := e.genDir(tab) if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("生成菜单失败!错误详情:%s", err.Error())) return } aList, aDetail := e.GenQueryApis(tab) cMenu, err := e.genMenu(tab, menu.MenuId, aList, aDetail) if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("生成菜单失败!错误详情:%s", err.Error())) return } err = e.genListBtn(tab, cMenu.MenuId, aList, aDetail) if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("生成菜单失败!错误详情:%s", err.Error())) return } err = e.genCreateBtn(tab, cMenu.MenuId) if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("生成菜单失败!错误详情:%s", err.Error())) return } err = e.genUpdateBtn(tab, cMenu.MenuId) if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("生成菜单失败!错误详情:%s", err.Error())) return } err = e.genDeleteBtn(tab, cMenu.MenuId) if err != nil { e.Logger.Error(err) e.Error(500, err, fmt.Sprintf("生成菜单失败!错误详情:%s", err.Error())) return } e.OK("", "数据生成成功!") } func (e Gen) genDir(tab tools.SysTables) (*models.SysMenu, error) { var err error menu := &models.SysMenu{} e.Orm.Model(menu).First(menu, models.SysMenu{Path: tab.PackageName, MenuType: global.Directory}) if menu.MenuId == 0 { menu = &models.SysMenu{} menu.MenuName = tab.TableComment menu.Icon = "pass" menu.Path = tab.PackageName menu.MenuType = global.Directory menu.Action = "" menu.ParentId = 0 menu.NoCache = false menu.Component = "Layout" menu.Sort = 0 menu.IsHide = false menu.IsFrame = false menu.CreateBy = 1 e.Orm.Model(menu).Save(menu) s := &service.SysMenuService{} err = s.InIitPaths(e.Orm, menu) } return menu, err } func (e Gen) genMenu(tab tools.SysTables, menuId int, aList models.SysApi, aDetail models.SysApi) (*models.SysMenu, error) { var err error CMenu := &models.SysMenu{} e.Orm.Model(CMenu).Preload("SysApi").First(CMenu, models.SysMenu{Path: tab.BusinessName, MenuType: global.Menu, ParentId: menuId}) if CMenu.MenuId != 0 { err := e.Orm.Model(CMenu).Association("SysApi").Delete(CMenu.SysApi) if err != nil { return nil, err } } CMenu.MenuName = tab.TableComment CMenu.Icon = "app-indicator" CMenu.Path = tab.BusinessName CMenu.MenuType = global.Menu CMenu.Action = "" CMenu.Permission = tab.PackageName + ":" + tab.BusinessName CMenu.ParentId = menuId CMenu.NoCache = false CMenu.Component = "/" + tab.PackageName + "/" + tab.BusinessName + "/index" CMenu.Sort = 1 CMenu.IsHide = false CMenu.IsFrame = false CMenu.CreateBy = 1 CMenu.UpdateBy = 1 CMenu.SysApi = []models.SysApi{aList, aDetail} e.Orm.Model(CMenu).Session(&gorm.Session{FullSaveAssociations: true}).Save(CMenu) s := &service.SysMenuService{} err = s.InIitPaths(e.Orm, CMenu) return CMenu, err } func (e Gen) genListBtn(tab tools.SysTables, menuId int, aList models.SysApi, aDetail models.SysApi) error { MList := &models.SysMenu{} menuPath := "#" menuIcon := "eye" e.Orm.Model(MList).Preload("SysApi").First(MList, models.SysMenu{Path: menuPath, Icon: menuIcon, MenuType: global.Button, ParentId: menuId}) if MList.MenuId != 0 { err := e.Orm.Model(MList).Association("SysApi").Delete(MList.SysApi) if err != nil { return err } } MList.MenuName = "查询" + tab.FunctionName MList.Icon = menuIcon MList.Path = menuPath MList.MenuType = global.Button MList.Action = "" MList.Permission = tab.PackageName + ":" + tab.BusinessName + ":query" MList.ParentId = menuId MList.NoCache = false MList.Sort = 1 MList.IsHide = true MList.IsFrame = false MList.SysApi = []models.SysApi{aList, aDetail} MList.CreateBy = 1 MList.UpdateBy = 1 e.Orm.Model(MList).Session(&gorm.Session{FullSaveAssociations: true}).Save(MList) //if MList.MenuId == 0 { // e.Orm.Model(MList).Session(&gorm.Session{FullSaveAssociations: true}).Create(MList) //} else { // e.Orm.Model(MList).Session(&gorm.Session{FullSaveAssociations: true}).Save(MList) //} s := &service.SysMenuService{} err := s.InIitPaths(e.Orm, MList) return err } func (e Gen) GenQueryApis(tab tools.SysTables) (models.SysApi, models.SysApi) { AList := models.SysApi{} handle := "IotAdmin/app/" + tab.PackageName + "/apis.(*" + tab.ClassName + "Api).GetPage-fm" title := "获取" + tab.FunctionName + "列表" path := "/api/" + tab.ModuleName action := "GET" e.Orm.Model(&AList).Where(models.SysApi{Path: path, Action: action}).Assign(models.SysApi{ Handle: handle, Title: title, Type: "BUS", }).FirstOrCreate(&AList) ADetail := models.SysApi{} handle2 := "IotAdmin/app/" + tab.PackageName + "/apis.(*" + tab.ClassName + "Api).Get-fm" title2 := "获取" + tab.FunctionName + "详情" path2 := "/api/" + tab.ModuleName + "/:" + tab.PkColumn action2 := "GET" e.Orm.Model(&ADetail).Where(models.SysApi{Path: path2, Action: action2}).Assign(models.SysApi{ Handle: handle2, Title: title2, Type: "BUS", }).FirstOrCreate(&ADetail) return AList, ADetail } func (e Gen) genCreateBtn(tab tools.SysTables, menuId int) error { ACreate := models.SysApi{} handle := "IotAdmin/app/" + tab.PackageName + "/apis.(*" + tab.ClassName + "Api).Insert-fm" title := "添加" + tab.FunctionName path := "/api/" + tab.ModuleName action := "POST" e.Orm.Model(&ACreate).Where(models.SysApi{Path: path, Action: action}).Assign(models.SysApi{ Handle: handle, Title: title, Type: "BUS", }).FirstOrCreate(&ACreate) menuIcon := "plus-square" menuPath := "#" MCreate := &models.SysMenu{} e.Orm.Model(MCreate).Preload("SysApi").First(MCreate, models.SysMenu{Path: menuPath, Icon: menuIcon, MenuType: global.Button, ParentId: menuId}) if MCreate.MenuId != 0 { err := e.Orm.Model(&MCreate).Association("SysApi").Delete(MCreate.SysApi) if err != nil { return err } } MCreate.MenuName = "新增" + tab.FunctionName MCreate.Icon = menuIcon MCreate.Path = menuPath MCreate.MenuType = global.Button MCreate.Action = "" MCreate.Permission = tab.PackageName + ":" + tab.BusinessName + ":add" MCreate.ParentId = menuId MCreate.NoCache = false MCreate.Sort = 2 MCreate.BtnClass = "btn btn-light-primary" MCreate.BtnScript = "handleCreate" MCreate.IsHide = false MCreate.IsFrame = false MCreate.SysApi = []models.SysApi{ACreate} MCreate.CreateBy = 1 MCreate.UpdateBy = 1 e.Orm.Model(MCreate).Session(&gorm.Session{FullSaveAssociations: true}).Save(MCreate) //if MCreate.MenuId == 0 { // e.Orm.Model(MCreate).Session(&gorm.Session{FullSaveAssociations: true}).Create(MCreate) //} else { // e.Orm.Model(MCreate).Session(&gorm.Session{FullSaveAssociations: true}).Save(MCreate) //} s := &service.SysMenuService{} err := s.InIitPaths(e.Orm, MCreate) return err } func (e Gen) genUpdateBtn(tab tools.SysTables, menuId int) error { AUpdate := models.SysApi{} handle := "IotAdmin/app/" + tab.PackageName + "/apis.(*" + tab.ClassName + "Api).Update-fm" title := "修改" + tab.FunctionName path := "/api/" + tab.ModuleName + "/:" + tab.PkColumn action := "PUT" e.Orm.Model(&AUpdate).Where(models.SysApi{Path: path, Action: action}).Assign(models.SysApi{ Handle: handle, Title: title, Type: "BUS", }).FirstOrCreate(&AUpdate) menuIcon := "pencil-square" menuPath := "#" MUpdate := &models.SysMenu{} e.Orm.Debug().Model(MUpdate).Preload("SysApi").First(MUpdate, models.SysMenu{Path: menuPath, Icon: menuIcon, MenuType: global.Button, ParentId: menuId}) if MUpdate.MenuId != 0 { err := e.Orm.Model(MUpdate).Association("SysApi").Delete(MUpdate.SysApi) if err != nil { return err } } MUpdate.MenuName = "修改" + tab.FunctionName MUpdate.Icon = menuIcon MUpdate.Path = menuPath MUpdate.MenuType = global.Button MUpdate.Action = "" MUpdate.Permission = tab.PackageName + ":" + tab.BusinessName + ":edit" MUpdate.ParentId = menuId MUpdate.NoCache = false MUpdate.Sort = 3 MUpdate.BtnClass = "btn btn-light-success" MUpdate.BtnScript = "handleUpdate@1" MUpdate.IsHide = false MUpdate.IsFrame = false MUpdate.SysApi = []models.SysApi{AUpdate} MUpdate.CreateBy = 1 MUpdate.UpdateBy = 1 e.Orm.Model(MUpdate).Session(&gorm.Session{FullSaveAssociations: true}).Save(MUpdate) //if MUpdate.MenuId == 0 { // e.Orm.Model(MUpdate).Session(&gorm.Session{FullSaveAssociations: true}).Create(MUpdate) //} else { // e.Orm.Model(MUpdate).Session(&gorm.Session{FullSaveAssociations: true}).Save(MUpdate) //} s := &service.SysMenuService{} err := s.InIitPaths(e.Orm, MUpdate) return err } func (e Gen) genDeleteBtn(tab tools.SysTables, menuId int) error { ADelete := models.SysApi{} handle := "IotAdmin/app/" + tab.PackageName + "/apis.(*" + tab.ClassName + "Api).Delete-fm" title := "删除" + tab.FunctionName path := "/api/" + tab.ModuleName action := "DELETE" e.Orm.Model(&ADelete).Where(models.SysApi{Path: path, Action: action}).Assign(models.SysApi{ Handle: handle, Title: title, Type: "BUS", }).FirstOrCreate(&ADelete) menuIcon := "dash-square" menuPath := "#" MDelete := &models.SysMenu{} e.Orm.Model(MDelete).Preload("SysApi").First(MDelete, models.SysMenu{Path: menuPath, Icon: menuIcon, MenuType: global.Button, ParentId: menuId}) if MDelete.MenuId != 0 { err := e.Orm.Model(MDelete).Association("SysApi").Delete(MDelete.SysApi) if err != nil { return err } } MDelete.MenuName = "删除" + tab.FunctionName MDelete.Icon = menuIcon MDelete.Path = menuPath MDelete.MenuType = global.Button MDelete.Action = "" MDelete.Permission = tab.PackageName + ":" + tab.BusinessName + ":remove" MDelete.ParentId = menuId MDelete.NoCache = false MDelete.Sort = 4 MDelete.BtnClass = "btn btn-light-danger" MDelete.BtnScript = "handleDelete@0" MDelete.IsHide = false MDelete.IsFrame = false MDelete.SysApi = []models.SysApi{ADelete} MDelete.CreateBy = 1 MDelete.UpdateBy = 1 e.Orm.Model(MDelete).Session(&gorm.Session{FullSaveAssociations: true}).Save(MDelete) //if MDelete.MenuId == 0 { // e.Orm.Model(MDelete).Session(&gorm.Session{FullSaveAssociations: true}).Create(MDelete) //} else { // e.Orm.Model(MDelete).Session(&gorm.Session{FullSaveAssociations: true}).Save(MDelete) //} s := &service.SysMenuService{} err := s.InIitPaths(e.Orm, MDelete) return err }