auto_code_package.go 30 KB

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