auto_code_package.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. package system
  2. import (
  3. "context"
  4. "fmt"
  5. "go/token"
  6. "os"
  7. "path/filepath"
  8. "strings"
  9. "text/template"
  10. "github.com/flipped-aurora/gin-vue-admin/server/global"
  11. common "github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
  12. model "github.com/flipped-aurora/gin-vue-admin/server/model/system"
  13. "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
  14. "github.com/flipped-aurora/gin-vue-admin/server/utils"
  15. "github.com/flipped-aurora/gin-vue-admin/server/utils/ast"
  16. "github.com/pkg/errors"
  17. "gorm.io/gorm"
  18. )
  19. var AutoCodePackage = new(autoCodePackage)
  20. type autoCodePackage struct{}
  21. // Create 创建包信息
  22. // @author: [piexlmax](https://github.com/piexlmax)
  23. // @author: [SliverHorn](https://github.com/SliverHorn)
  24. func (s *autoCodePackage) Create(ctx context.Context, info *request.SysAutoCodePackageCreate) error {
  25. switch {
  26. case info.Template == "":
  27. return errors.New("模板不能为空!")
  28. case info.Template == "page":
  29. return errors.New("page为表单生成器!")
  30. case info.PackageName == "":
  31. return errors.New("PackageName不能为空!")
  32. case token.IsKeyword(info.PackageName):
  33. return errors.Errorf("%s为go的关键字!", info.PackageName)
  34. case info.Template == "package":
  35. if info.PackageName == "system" || info.PackageName == "example" {
  36. return errors.New("不能使用已保留的package name")
  37. }
  38. default:
  39. break
  40. }
  41. if !errors.Is(global.GVA_DB.Where("package_name = ? and template = ?", info.PackageName, info.Template).First(&model.SysAutoCodePackage{}).Error, gorm.ErrRecordNotFound) {
  42. return errors.New("存在相同PackageName")
  43. }
  44. create := info.Create()
  45. return global.GVA_DB.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
  46. err := tx.Create(&create).Error
  47. if err != nil {
  48. return errors.Wrap(err, "创建失败!")
  49. }
  50. code := info.AutoCode()
  51. _, asts, creates, err := s.templates(ctx, create, code, true)
  52. if err != nil {
  53. return err
  54. }
  55. for key, value := range creates { // key 为 模版绝对路径
  56. var files *template.Template
  57. files, err = template.ParseFiles(key)
  58. if err != nil {
  59. return errors.Wrapf(err, "[filepath:%s]读取模版文件失败!", key)
  60. }
  61. err = os.MkdirAll(filepath.Dir(value), os.ModePerm)
  62. if err != nil {
  63. return errors.Wrapf(err, "[filepath:%s]创建文件夹失败!", value)
  64. }
  65. var file *os.File
  66. file, err = os.Create(value)
  67. if err != nil {
  68. return errors.Wrapf(err, "[filepath:%s]创建文件夹失败!", value)
  69. }
  70. err = files.Execute(file, code)
  71. _ = file.Close()
  72. if err != nil {
  73. return errors.Wrapf(err, "[filepath:%s]生成失败!", value)
  74. }
  75. fmt.Printf("[template:%s][filepath:%s]生成成功!\n", key, value)
  76. }
  77. for key, value := range asts {
  78. keys := strings.Split(key, "=>")
  79. if len(keys) == 2 {
  80. switch keys[1] {
  81. case ast.TypePluginInitializeV2, ast.TypePackageApiEnter, ast.TypePackageRouterEnter, ast.TypePackageServiceEnter:
  82. file, _ := value.Parse("", nil)
  83. if file != nil {
  84. err = value.Injection(file)
  85. if err != nil {
  86. return err
  87. }
  88. err = value.Format("", nil, file)
  89. if err != nil {
  90. return err
  91. }
  92. }
  93. fmt.Printf("[type:%s]注入成功!\n", key)
  94. }
  95. }
  96. }
  97. return nil
  98. })
  99. }
  100. // Delete 删除包记录
  101. // @author: [piexlmax](https://github.com/piexlmax)
  102. // @author: [SliverHorn](https://github.com/SliverHorn)
  103. func (s *autoCodePackage) Delete(ctx context.Context, info common.GetById) error {
  104. err := global.GVA_DB.WithContext(ctx).Delete(&model.SysAutoCodePackage{}, info.Uint()).Error
  105. if err != nil {
  106. return errors.Wrap(err, "删除失败!")
  107. }
  108. return nil
  109. }
  110. // All 获取所有包
  111. // @author: [piexlmax](https://github.com/piexlmax)
  112. // @author: [SliverHorn](https://github.com/SliverHorn)
  113. func (s *autoCodePackage) All(ctx context.Context) (entities []model.SysAutoCodePackage, err error) {
  114. server := make([]model.SysAutoCodePackage, 0)
  115. plugin := make([]model.SysAutoCodePackage, 0)
  116. serverPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "service")
  117. pluginPath := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin")
  118. serverDir, err := os.ReadDir(serverPath)
  119. if err != nil {
  120. return nil, errors.Wrap(err, "读取service文件夹失败!")
  121. }
  122. pluginDir, err := os.ReadDir(pluginPath)
  123. if err != nil {
  124. return nil, errors.Wrap(err, "读取plugin文件夹失败!")
  125. }
  126. for i := 0; i < len(serverDir); i++ {
  127. if serverDir[i].IsDir() {
  128. serverPackage := model.SysAutoCodePackage{
  129. PackageName: serverDir[i].Name(),
  130. Template: "package",
  131. Label: serverDir[i].Name() + "包",
  132. Desc: "系统自动读取" + serverDir[i].Name() + "包",
  133. Module: global.GVA_CONFIG.AutoCode.Module,
  134. }
  135. server = append(server, serverPackage)
  136. }
  137. }
  138. for i := 0; i < len(pluginDir); i++ {
  139. if pluginDir[i].IsDir() {
  140. dirNameMap := map[string]bool{
  141. "api": true,
  142. "config": true,
  143. "initialize": true,
  144. "model": true,
  145. "plugin": true,
  146. "router": true,
  147. "service": true,
  148. }
  149. dir, e := os.ReadDir(filepath.Join(pluginPath, pluginDir[i].Name()))
  150. if e != nil {
  151. return nil, errors.Wrap(err, "读取plugin文件夹失败!")
  152. }
  153. //dir目录需要包含所有的dirNameMap
  154. for k := 0; k < len(dir); k++ {
  155. if dir[k].IsDir() {
  156. if ok := dirNameMap[dir[k].Name()]; ok {
  157. delete(dirNameMap, dir[k].Name())
  158. }
  159. }
  160. }
  161. if len(dirNameMap) != 0 {
  162. continue
  163. }
  164. pluginPackage := model.SysAutoCodePackage{
  165. PackageName: pluginDir[i].Name(),
  166. Template: "plugin",
  167. Label: pluginDir[i].Name() + "插件",
  168. Desc: "系统自动读取" + pluginDir[i].Name() + "插件,使用前请确认是否为v2版本插件",
  169. Module: global.GVA_CONFIG.AutoCode.Module,
  170. }
  171. plugin = append(plugin, pluginPackage)
  172. }
  173. }
  174. err = global.GVA_DB.WithContext(ctx).Find(&entities).Error
  175. if err != nil {
  176. return nil, errors.Wrap(err, "获取所有包失败!")
  177. }
  178. entitiesMap := make(map[string]model.SysAutoCodePackage)
  179. for i := 0; i < len(entities); i++ {
  180. entitiesMap[entities[i].PackageName] = entities[i]
  181. }
  182. createEntity := []model.SysAutoCodePackage{}
  183. for i := 0; i < len(server); i++ {
  184. if _, ok := entitiesMap[server[i].PackageName]; !ok {
  185. if server[i].Template == "package" {
  186. createEntity = append(createEntity, server[i])
  187. }
  188. }
  189. }
  190. for i := 0; i < len(plugin); i++ {
  191. if _, ok := entitiesMap[plugin[i].PackageName]; !ok {
  192. if plugin[i].Template == "plugin" {
  193. createEntity = append(createEntity, plugin[i])
  194. }
  195. }
  196. }
  197. if len(createEntity) > 0 {
  198. err = global.GVA_DB.WithContext(ctx).Create(&createEntity).Error
  199. if err != nil {
  200. return nil, errors.Wrap(err, "同步失败!")
  201. }
  202. entities = append(entities, createEntity...)
  203. }
  204. return entities, nil
  205. }
  206. // Templates 获取所有模版文件夹
  207. // @author: [SliverHorn](https://github.com/SliverHorn)
  208. func (s *autoCodePackage) Templates(ctx context.Context) ([]string, error) {
  209. templates := make([]string, 0)
  210. entries, err := os.ReadDir("resource")
  211. if err != nil {
  212. return nil, errors.Wrap(err, "读取模版文件夹失败!")
  213. }
  214. for i := 0; i < len(entries); i++ {
  215. if entries[i].IsDir() {
  216. if entries[i].Name() == "page" {
  217. continue
  218. } // page 为表单生成器
  219. if entries[i].Name() == "function" {
  220. continue
  221. } // function 为函数生成器
  222. if entries[i].Name() == "preview" {
  223. continue
  224. } // preview 为预览代码生成器的代码
  225. templates = append(templates, entries[i].Name())
  226. }
  227. }
  228. return templates, nil
  229. }
  230. func (s *autoCodePackage) templates(ctx context.Context, entity model.SysAutoCodePackage, info request.AutoCode, isPackage bool) (code map[string]string, asts map[string]ast.Ast, creates map[string]string, err error) {
  231. code = make(map[string]string)
  232. asts = make(map[string]ast.Ast)
  233. creates = make(map[string]string)
  234. templateDir := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "resource", entity.Template)
  235. templateDirs, err := os.ReadDir(templateDir)
  236. if err != nil {
  237. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", templateDir)
  238. }
  239. for i := 0; i < len(templateDirs); i++ {
  240. second := filepath.Join(templateDir, templateDirs[i].Name())
  241. switch templateDirs[i].Name() {
  242. case "server":
  243. if !info.GenerateServer && !isPackage {
  244. break
  245. }
  246. var secondDirs []os.DirEntry
  247. secondDirs, err = os.ReadDir(second)
  248. if err != nil {
  249. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", second)
  250. }
  251. for j := 0; j < len(secondDirs); j++ {
  252. if secondDirs[j].Name() == ".DS_Store" {
  253. continue
  254. }
  255. three := filepath.Join(second, secondDirs[j].Name())
  256. if !secondDirs[j].IsDir() {
  257. ext := filepath.Ext(secondDirs[j].Name())
  258. if ext != ".template" && ext != ".tpl" {
  259. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版后缀!", three)
  260. }
  261. name := strings.TrimSuffix(secondDirs[j].Name(), ext)
  262. if name == "main.go" || name == "plugin.go" {
  263. pluginInitialize := &ast.PluginInitializeV2{
  264. Type: ast.TypePluginInitializeV2,
  265. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, name),
  266. PluginPath: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "initialize", "plugin_biz_v2.go"),
  267. ImportPath: fmt.Sprintf(`"%s/plugin/%s"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName),
  268. PackageName: entity.PackageName,
  269. }
  270. asts[pluginInitialize.PluginPath+"=>"+pluginInitialize.Type.String()] = pluginInitialize
  271. creates[three] = pluginInitialize.Path
  272. continue
  273. }
  274. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", three)
  275. }
  276. switch secondDirs[j].Name() {
  277. case "api", "router", "service":
  278. var threeDirs []os.DirEntry
  279. threeDirs, err = os.ReadDir(three)
  280. if err != nil {
  281. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", three)
  282. }
  283. for k := 0; k < len(threeDirs); k++ {
  284. if threeDirs[k].Name() == ".DS_Store" {
  285. continue
  286. }
  287. four := filepath.Join(three, threeDirs[k].Name())
  288. if threeDirs[k].IsDir() {
  289. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件夹!", four)
  290. }
  291. ext := filepath.Ext(four)
  292. if ext != ".template" && ext != ".tpl" {
  293. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版后缀!", four)
  294. }
  295. api := strings.Index(threeDirs[k].Name(), "api")
  296. hasEnter := strings.Index(threeDirs[k].Name(), "enter")
  297. router := strings.Index(threeDirs[k].Name(), "router")
  298. service := strings.Index(threeDirs[k].Name(), "service")
  299. if router == -1 && api == -1 && service == -1 && hasEnter == -1 {
  300. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", four)
  301. }
  302. if entity.Template == "package" {
  303. create := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), entity.PackageName, info.HumpPackageName+".go")
  304. if api != -1 {
  305. create = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), "v1", entity.PackageName, info.HumpPackageName+".go")
  306. }
  307. if hasEnter != -1 {
  308. isApi := strings.Index(secondDirs[j].Name(), "api")
  309. isRouter := strings.Index(secondDirs[j].Name(), "router")
  310. isService := strings.Index(secondDirs[j].Name(), "service")
  311. if isApi != -1 {
  312. packageApiEnter := &ast.PackageEnter{
  313. Type: ast.TypePackageApiEnter,
  314. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), "v1", "enter.go"),
  315. ImportPath: fmt.Sprintf(`"%s/%s/%s/%s"`, global.GVA_CONFIG.AutoCode.Module, "api", "v1", entity.PackageName),
  316. StructName: utils.FirstUpper(entity.PackageName) + "ApiGroup",
  317. PackageName: entity.PackageName,
  318. PackageStructName: "ApiGroup",
  319. }
  320. asts[packageApiEnter.Path+"=>"+packageApiEnter.Type.String()] = packageApiEnter
  321. packageApiModuleEnter := &ast.PackageModuleEnter{
  322. Type: ast.TypePackageApiModuleEnter,
  323. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), "v1", entity.PackageName, "enter.go"),
  324. ImportPath: fmt.Sprintf(`"%s/service"`, global.GVA_CONFIG.AutoCode.Module),
  325. StructName: info.StructName + "Api",
  326. AppName: "ServiceGroupApp",
  327. GroupName: utils.FirstUpper(entity.PackageName) + "ServiceGroup",
  328. ModuleName: info.Abbreviation + "Service",
  329. PackageName: "service",
  330. ServiceName: info.StructName + "Service",
  331. }
  332. asts[packageApiModuleEnter.Path+"=>"+packageApiModuleEnter.Type.String()] = packageApiModuleEnter
  333. creates[four] = packageApiModuleEnter.Path
  334. }
  335. if isRouter != -1 {
  336. packageRouterEnter := &ast.PackageEnter{
  337. Type: ast.TypePackageRouterEnter,
  338. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), "enter.go"),
  339. ImportPath: fmt.Sprintf(`"%s/%s/%s"`, global.GVA_CONFIG.AutoCode.Module, secondDirs[j].Name(), entity.PackageName),
  340. StructName: utils.FirstUpper(entity.PackageName),
  341. PackageName: entity.PackageName,
  342. PackageStructName: "RouterGroup",
  343. }
  344. asts[packageRouterEnter.Path+"=>"+packageRouterEnter.Type.String()] = packageRouterEnter
  345. packageRouterModuleEnter := &ast.PackageModuleEnter{
  346. Type: ast.TypePackageRouterModuleEnter,
  347. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), entity.PackageName, "enter.go"),
  348. ImportPath: fmt.Sprintf(`api "%s/api/v1"`, global.GVA_CONFIG.AutoCode.Module),
  349. StructName: info.StructName + "Router",
  350. AppName: "ApiGroupApp",
  351. GroupName: utils.FirstUpper(entity.PackageName) + "ApiGroup",
  352. ModuleName: info.Abbreviation + "Api",
  353. PackageName: "api",
  354. ServiceName: info.StructName + "Api",
  355. }
  356. creates[four] = packageRouterModuleEnter.Path
  357. asts[packageRouterModuleEnter.Path+"=>"+packageRouterModuleEnter.Type.String()] = packageRouterModuleEnter
  358. packageInitializeRouter := &ast.PackageInitializeRouter{
  359. Type: ast.TypePackageInitializeRouter,
  360. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "initialize", "router_biz.go"),
  361. ImportPath: fmt.Sprintf(`"%s/router"`, global.GVA_CONFIG.AutoCode.Module),
  362. AppName: "RouterGroupApp",
  363. GroupName: utils.FirstUpper(entity.PackageName),
  364. ModuleName: entity.PackageName + "Router",
  365. PackageName: "router",
  366. FunctionName: "Init" + info.StructName + "Router",
  367. LeftRouterGroupName: "privateGroup",
  368. RightRouterGroupName: "publicGroup",
  369. }
  370. asts[packageInitializeRouter.Path+"=>"+packageInitializeRouter.Type.String()] = packageInitializeRouter
  371. }
  372. if isService != -1 {
  373. path := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext))
  374. importPath := fmt.Sprintf(`"%s/service/%s"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName)
  375. packageServiceEnter := &ast.PackageEnter{
  376. Type: ast.TypePackageServiceEnter,
  377. Path: path,
  378. ImportPath: importPath,
  379. StructName: utils.FirstUpper(entity.PackageName) + "ServiceGroup",
  380. PackageName: entity.PackageName,
  381. PackageStructName: "ServiceGroup",
  382. }
  383. asts[packageServiceEnter.Path+"=>"+packageServiceEnter.Type.String()] = packageServiceEnter
  384. packageServiceModuleEnter := &ast.PackageModuleEnter{
  385. Type: ast.TypePackageServiceModuleEnter,
  386. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), entity.PackageName, "enter.go"),
  387. StructName: info.StructName + "Service",
  388. }
  389. asts[packageServiceModuleEnter.Path+"=>"+packageServiceModuleEnter.Type.String()] = packageServiceModuleEnter
  390. creates[four] = packageServiceModuleEnter.Path
  391. }
  392. continue
  393. }
  394. code[four] = create
  395. continue
  396. }
  397. if hasEnter != -1 {
  398. isApi := strings.Index(secondDirs[j].Name(), "api")
  399. isRouter := strings.Index(secondDirs[j].Name(), "router")
  400. isService := strings.Index(secondDirs[j].Name(), "service")
  401. if isRouter != -1 {
  402. pluginRouterEnter := &ast.PluginEnter{
  403. Type: ast.TypePluginRouterEnter,
  404. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext)),
  405. ImportPath: fmt.Sprintf(`"%s/plugin/%s/api"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName),
  406. StructName: info.StructName,
  407. StructCamelName: info.Abbreviation,
  408. ModuleName: "api" + info.StructName,
  409. GroupName: "Api",
  410. PackageName: "api",
  411. ServiceName: info.StructName,
  412. }
  413. asts[pluginRouterEnter.Path+"=>"+pluginRouterEnter.Type.String()] = pluginRouterEnter
  414. creates[four] = pluginRouterEnter.Path
  415. }
  416. if isApi != -1 {
  417. pluginApiEnter := &ast.PluginEnter{
  418. Type: ast.TypePluginApiEnter,
  419. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext)),
  420. ImportPath: fmt.Sprintf(`"%s/plugin/%s/service"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName),
  421. StructName: info.StructName,
  422. StructCamelName: info.Abbreviation,
  423. ModuleName: "service" + info.StructName,
  424. GroupName: "Service",
  425. PackageName: "service",
  426. ServiceName: info.StructName,
  427. }
  428. asts[pluginApiEnter.Path+"=>"+pluginApiEnter.Type.String()] = pluginApiEnter
  429. creates[four] = pluginApiEnter.Path
  430. }
  431. if isService != -1 {
  432. pluginServiceEnter := &ast.PluginEnter{
  433. Type: ast.TypePluginServiceEnter,
  434. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext)),
  435. StructName: info.StructName,
  436. StructCamelName: info.Abbreviation,
  437. }
  438. asts[pluginServiceEnter.Path+"=>"+pluginServiceEnter.Type.String()] = pluginServiceEnter
  439. creates[four] = pluginServiceEnter.Path
  440. }
  441. continue
  442. } // enter.go
  443. create := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), info.HumpPackageName+".go")
  444. code[four] = create
  445. }
  446. case "gen", "config", "initialize", "plugin", "response":
  447. if entity.Template == "package" {
  448. continue
  449. } // package模板不需要生成gen, config, initialize
  450. var threeDirs []os.DirEntry
  451. threeDirs, err = os.ReadDir(three)
  452. if err != nil {
  453. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", three)
  454. }
  455. for k := 0; k < len(threeDirs); k++ {
  456. if threeDirs[k].Name() == ".DS_Store" {
  457. continue
  458. }
  459. four := filepath.Join(three, threeDirs[k].Name())
  460. if threeDirs[k].IsDir() {
  461. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件夹!", four)
  462. }
  463. ext := filepath.Ext(four)
  464. if ext != ".template" && ext != ".tpl" {
  465. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版后缀!", four)
  466. }
  467. gen := strings.Index(threeDirs[k].Name(), "gen")
  468. api := strings.Index(threeDirs[k].Name(), "api")
  469. menu := strings.Index(threeDirs[k].Name(), "menu")
  470. viper := strings.Index(threeDirs[k].Name(), "viper")
  471. plugin := strings.Index(threeDirs[k].Name(), "plugin")
  472. config := strings.Index(threeDirs[k].Name(), "config")
  473. router := strings.Index(threeDirs[k].Name(), "router")
  474. hasGorm := strings.Index(threeDirs[k].Name(), "gorm")
  475. response := strings.Index(threeDirs[k].Name(), "response")
  476. if gen != -1 && api != -1 && menu != -1 && viper != -1 && plugin != -1 && config != -1 && router != -1 && hasGorm != -1 && response != -1 {
  477. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", four)
  478. }
  479. if api != -1 || menu != -1 || viper != -1 || response != -1 || plugin != -1 || config != -1 {
  480. creates[four] = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext))
  481. }
  482. if gen != -1 {
  483. pluginGen := &ast.PluginGen{
  484. Type: ast.TypePluginGen,
  485. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext)),
  486. ImportPath: fmt.Sprintf(`"%s/plugin/%s/model"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName),
  487. StructName: info.StructName,
  488. PackageName: "model",
  489. IsNew: true,
  490. }
  491. asts[pluginGen.Path+"=>"+pluginGen.Type.String()] = pluginGen
  492. creates[four] = pluginGen.Path
  493. }
  494. if hasGorm != -1 {
  495. pluginInitializeGorm := &ast.PluginInitializeGorm{
  496. Type: ast.TypePluginInitializeGorm,
  497. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext)),
  498. ImportPath: fmt.Sprintf(`"%s/plugin/%s/model"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName),
  499. StructName: info.StructName,
  500. PackageName: "model",
  501. IsNew: true,
  502. }
  503. asts[pluginInitializeGorm.Path+"=>"+pluginInitializeGorm.Type.String()] = pluginInitializeGorm
  504. creates[four] = pluginInitializeGorm.Path
  505. }
  506. if router != -1 {
  507. pluginInitializeRouter := &ast.PluginInitializeRouter{
  508. Type: ast.TypePluginInitializeRouter,
  509. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), strings.TrimSuffix(threeDirs[k].Name(), ext)),
  510. ImportPath: fmt.Sprintf(`"%s/plugin/%s/router"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName),
  511. AppName: "Router",
  512. GroupName: info.StructName,
  513. PackageName: "router",
  514. FunctionName: "Init",
  515. LeftRouterGroupName: "public",
  516. RightRouterGroupName: "private",
  517. }
  518. asts[pluginInitializeRouter.Path+"=>"+pluginInitializeRouter.Type.String()] = pluginInitializeRouter
  519. creates[four] = pluginInitializeRouter.Path
  520. }
  521. }
  522. case "model":
  523. var threeDirs []os.DirEntry
  524. threeDirs, err = os.ReadDir(three)
  525. if err != nil {
  526. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", three)
  527. }
  528. for k := 0; k < len(threeDirs); k++ {
  529. if threeDirs[k].Name() == ".DS_Store" {
  530. continue
  531. }
  532. four := filepath.Join(three, threeDirs[k].Name())
  533. if threeDirs[k].IsDir() {
  534. var fourDirs []os.DirEntry
  535. fourDirs, err = os.ReadDir(four)
  536. if err != nil {
  537. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", four)
  538. }
  539. for l := 0; l < len(fourDirs); l++ {
  540. if fourDirs[l].Name() == ".DS_Store" {
  541. continue
  542. }
  543. five := filepath.Join(four, fourDirs[l].Name())
  544. if fourDirs[l].IsDir() {
  545. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件夹!", five)
  546. }
  547. ext := filepath.Ext(five)
  548. if ext != ".template" && ext != ".tpl" {
  549. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版后缀!", five)
  550. }
  551. hasRequest := strings.Index(fourDirs[l].Name(), "request")
  552. if hasRequest == -1 {
  553. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", five)
  554. }
  555. create := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), threeDirs[k].Name(), info.HumpPackageName+".go")
  556. if entity.Template == "package" {
  557. create = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), entity.PackageName, threeDirs[k].Name(), info.HumpPackageName+".go")
  558. }
  559. code[five] = create
  560. }
  561. continue
  562. }
  563. ext := filepath.Ext(threeDirs[k].Name())
  564. if ext != ".template" && ext != ".tpl" {
  565. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版后缀!", four)
  566. }
  567. hasModel := strings.Index(threeDirs[k].Name(), "model")
  568. if hasModel == -1 {
  569. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", four)
  570. }
  571. create := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "plugin", entity.PackageName, secondDirs[j].Name(), info.HumpPackageName+".go")
  572. if entity.Template == "package" {
  573. packageInitializeGorm := &ast.PackageInitializeGorm{
  574. Type: ast.TypePackageInitializeGorm,
  575. Path: filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, "initialize", "gorm_biz.go"),
  576. ImportPath: fmt.Sprintf(`"%s/model/%s"`, global.GVA_CONFIG.AutoCode.Module, entity.PackageName),
  577. Business: info.BusinessDB,
  578. StructName: info.StructName,
  579. PackageName: entity.PackageName,
  580. IsNew: true,
  581. }
  582. code[four] = packageInitializeGorm.Path
  583. asts[packageInitializeGorm.Path+"=>"+packageInitializeGorm.Type.String()] = packageInitializeGorm
  584. create = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.Server, secondDirs[j].Name(), entity.PackageName, info.HumpPackageName+".go")
  585. }
  586. code[four] = create
  587. }
  588. default:
  589. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件夹!", three)
  590. }
  591. }
  592. case "web":
  593. if !info.GenerateWeb && !isPackage {
  594. break
  595. }
  596. var secondDirs []os.DirEntry
  597. secondDirs, err = os.ReadDir(second)
  598. if err != nil {
  599. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", second)
  600. }
  601. for j := 0; j < len(secondDirs); j++ {
  602. if secondDirs[j].Name() == ".DS_Store" {
  603. continue
  604. }
  605. three := filepath.Join(second, secondDirs[j].Name())
  606. if !secondDirs[j].IsDir() {
  607. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", three)
  608. }
  609. switch secondDirs[j].Name() {
  610. case "api", "form", "view", "table":
  611. var threeDirs []os.DirEntry
  612. threeDirs, err = os.ReadDir(three)
  613. if err != nil {
  614. return nil, nil, nil, errors.Wrapf(err, "读取模版文件夹[%s]失败!", three)
  615. }
  616. for k := 0; k < len(threeDirs); k++ {
  617. if threeDirs[k].Name() == ".DS_Store" {
  618. continue
  619. }
  620. four := filepath.Join(three, threeDirs[k].Name())
  621. if threeDirs[k].IsDir() {
  622. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件夹!", four)
  623. }
  624. ext := filepath.Ext(four)
  625. if ext != ".template" && ext != ".tpl" {
  626. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版后缀!", four)
  627. }
  628. api := strings.Index(threeDirs[k].Name(), "api")
  629. form := strings.Index(threeDirs[k].Name(), "form")
  630. view := strings.Index(threeDirs[k].Name(), "view")
  631. table := strings.Index(threeDirs[k].Name(), "table")
  632. if api == -1 && form == -1 && view == -1 && table == -1 {
  633. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", four)
  634. }
  635. if entity.Template == "package" {
  636. if view != -1 || table != -1 {
  637. formPath := filepath.Join(three, "form.vue"+ext)
  638. value, ok := code[formPath]
  639. if ok {
  640. value = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.WebRoot(), secondDirs[j].Name(), entity.PackageName, info.PackageName, info.PackageName+"Form"+filepath.Ext(strings.TrimSuffix(threeDirs[k].Name(), ext)))
  641. code[formPath] = value
  642. }
  643. }
  644. create := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.WebRoot(), secondDirs[j].Name(), entity.PackageName, info.PackageName, info.PackageName+filepath.Ext(strings.TrimSuffix(threeDirs[k].Name(), ext)))
  645. if api != -1 {
  646. create = filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.WebRoot(), secondDirs[j].Name(), entity.PackageName, info.PackageName+filepath.Ext(strings.TrimSuffix(threeDirs[k].Name(), ext)))
  647. }
  648. code[four] = create
  649. continue
  650. }
  651. create := filepath.Join(global.GVA_CONFIG.AutoCode.Root, global.GVA_CONFIG.AutoCode.WebRoot(), "plugin", entity.PackageName, secondDirs[j].Name(), info.PackageName+filepath.Ext(strings.TrimSuffix(threeDirs[k].Name(), ext)))
  652. code[four] = create
  653. }
  654. default:
  655. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件夹!", three)
  656. }
  657. }
  658. case "readme.txt.tpl", "readme.txt.template":
  659. continue
  660. default:
  661. if templateDirs[i].Name() == ".DS_Store" {
  662. continue
  663. }
  664. return nil, nil, nil, errors.Errorf("[filpath:%s]非法模版文件!", second)
  665. }
  666. }
  667. return code, asts, creates, nil
  668. }