code_api.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. package admin
  2. import (
  3. "fmt"
  4. "github.com/druidcaesa/gotool"
  5. "html/template"
  6. "io/ioutil"
  7. "log"
  8. "os"
  9. "path"
  10. "strings"
  11. "ulink-admin/frame"
  12. "ulink-admin/modules/system/models/dto"
  13. req "ulink-admin/modules/system/models/req"
  14. "ulink-admin/modules/system/service"
  15. "ulink-admin/pkg/file"
  16. "ulink-admin/pkg/page"
  17. "ulink-admin/utils"
  18. "ulink-admin/utils/dataType"
  19. )
  20. // CodeApi 代码生成操作api
  21. type CodeApi struct {
  22. CodeService *service.CodeService `inject:""`
  23. MenuService *service.MenuService `inject:""`
  24. }
  25. // Find 查询数据库表信息列表
  26. func (ctr *CodeApi) FindTable(c *frame.Context) {
  27. query := req.TableQuery{}
  28. c.ValidteError(c.BindQuery(&query), query)
  29. list, i := ctr.CodeService.FindTable(query)
  30. c.Ok(page.Page{
  31. Size: query.PageSize,
  32. Total: i,
  33. List: list,
  34. })
  35. }
  36. // Find 查询数据库表信息列表
  37. func (ctr *CodeApi) FindOne(c *frame.Context) {
  38. query := req.TableQuery{}
  39. c.ValidteError(c.BindQuery(&query), query)
  40. list, _ := ctr.CodeService.FindTable(query)
  41. c.Ok(list[0])
  42. }
  43. // Find 查询数据库表信息列表
  44. func (ctr *CodeApi) FindColumn(c *frame.Context) {
  45. query := req.ColnumQuery{}
  46. c.ValidteError(c.BindQuery(&query), query)
  47. list, i := ctr.CodeService.FindColumn(query)
  48. c.Ok(page.Page{
  49. Size: query.PageSize,
  50. Total: i,
  51. List: list,
  52. })
  53. }
  54. // Generate 生成代码
  55. func (ctr *CodeApi) Generate(c *frame.Context) {
  56. codeBody := &req.CodeBody{}
  57. c.ValidteError(c.ShouldBindJSON(codeBody), codeBody)
  58. //进行数据处理
  59. codeBody.ClassNameUpper = utils.Ucfirst(codeBody.ClassName)
  60. codeBody.ClassName = codeBody.ClassNameUpper
  61. codeBody.ClassNameLower = strings.ToLower(codeBody.ClassName)
  62. codeBody.ClassNameCamel = utils.Lcfirst(codeBody.ClassName)
  63. codeBody.Width = 50 + (codeBody.Cols-1)*10
  64. codeBody.IsHaveTree = "0"
  65. colors := []string{"#F5F5F5", "#6495ED", " #43CD80", "#FF4040"}
  66. //codeBody.PrimaryKey=
  67. for index, value := range codeBody.Columns {
  68. if codeBody.Columns[index].HtmlType == "treeSelect" {
  69. codeBody.IsHaveTree = "1"
  70. }
  71. if codeBody.Columns[index].HtmlType == "imageUpload" {
  72. codeBody.IsHaveImage = "1"
  73. }
  74. if codeBody.Columns[index].HtmlType == "fileUpload" {
  75. codeBody.IsHaveFile = "1"
  76. }
  77. codeBody.Columns[index].ColumnNameUpper = utils.Ucfirst(utils.Case2Camel(value.ColumnName))
  78. codeBody.Columns[index].ColumnNameLower = utils.Lcfirst(utils.Case2Camel(value.ColumnName))
  79. codeBody.Columns[index].GoType = dataType.TypeConvert(value.DataType)
  80. if gotool.StrUtils.HasNotEmpty(codeBody.Columns[index].DictType) {
  81. codeBody.Columns[index].Source = "1"
  82. }
  83. if gotool.StrUtils.HasNotEmpty(codeBody.Columns[index].Menu) {
  84. codeBody.Columns[index].Source = "2"
  85. //查询引用的父级模块
  86. menu := ctr.MenuService.GetMenuByCon(&req.MenuQuery{Path: codeBody.Columns[index].Menu})
  87. if menu != nil {
  88. menu := ctr.MenuService.GetMenuByMenuId(menu.ParentId)
  89. if menu.Id > 0 {
  90. codeBody.Columns[index].Module = menu.Path
  91. }
  92. }
  93. }
  94. keys := ""
  95. if gotool.StrUtils.HasNotEmpty(codeBody.Columns[index].Input) {
  96. codeBody.Columns[index].Source = "3"
  97. ary := strings.Split(codeBody.Columns[index].Input, ",")
  98. sourceData := []req.SourceData{}
  99. for i, s := range ary {
  100. keys = keys + strings.Split(s, "=")[0] + " "
  101. code := strings.Split(s, "=")[0]
  102. label := strings.Split(s, "=")[1]
  103. var color string
  104. if i < 4 {
  105. color = colors[i]
  106. } else {
  107. color = colors[1]
  108. }
  109. sourceData = append(sourceData, req.SourceData{code, label, color})
  110. }
  111. codeBody.Columns[index].Keys = keys
  112. codeBody.Columns[index].Data = sourceData
  113. }
  114. }
  115. for index, value := range codeBody.SubColumns {
  116. codeBody.SubColumns[index].ColumnNameUpper = utils.Ucfirst(utils.Case2Camel(value.ColumnName))
  117. codeBody.SubColumns[index].ColumnNameLower = utils.Lcfirst(utils.Case2Camel(value.ColumnName))
  118. codeBody.SubColumns[index].GoType = dataType.TypeConvert(value.DataType)
  119. if gotool.StrUtils.HasNotEmpty(codeBody.SubColumns[index].DictType) {
  120. codeBody.SubColumns[index].Source = "1"
  121. }
  122. if gotool.StrUtils.HasNotEmpty(codeBody.SubColumns[index].Menu) {
  123. codeBody.SubColumns[index].Source = "2"
  124. }
  125. if gotool.StrUtils.HasNotEmpty(codeBody.SubColumns[index].Input) {
  126. codeBody.SubColumns[index].Source = "3"
  127. ary := strings.Split(codeBody.SubColumns[index].Input, ",")
  128. sourceData := []req.SourceData{}
  129. for i, s := range ary {
  130. code := strings.Split(s, "=")[0]
  131. label := strings.Split(s, "=")[1]
  132. var color string
  133. if i < 4 {
  134. color = colors[i]
  135. } else {
  136. color = colors[1]
  137. }
  138. sourceData = append(sourceData, req.SourceData{code, label, color})
  139. }
  140. codeBody.SubColumns[index].Data = sourceData
  141. }
  142. }
  143. codeBody.Controls = []string{}
  144. if codeBody.IsHaveTree == "1" {
  145. codeBody.Controls = append(codeBody.Controls, "Treeselect")
  146. }
  147. if codeBody.IsHaveImage == "1" {
  148. codeBody.Controls = append(codeBody.Controls, "ImageUpload")
  149. }
  150. if codeBody.IsHaveFile == "1" {
  151. codeBody.Controls = append(codeBody.Controls, "FileUpload")
  152. }
  153. //清除目录
  154. dir, _ := ioutil.ReadDir("./temporary/code")
  155. for _, d := range dir {
  156. os.RemoveAll(path.Join([]string{"./temporary/code", d.Name()}...))
  157. }
  158. //生成后端
  159. tpls := [7]dto.TemplateInfo{
  160. dto.TemplateInfo{"model.tpl", "modules/" + codeBody.ModuleName + "/models/model/", utils.Camel2Case(codeBody.ClassNameCamel) + ".go"},
  161. dto.TemplateInfo{"req.tpl", "modules/" + codeBody.ModuleName + "/models/req/", utils.Camel2Case(codeBody.ClassNameCamel) + "_request.go"},
  162. dto.TemplateInfo{"resp.tpl", "modules/" + codeBody.ModuleName + "/models/response/", utils.Camel2Case(codeBody.ClassNameCamel) + "_response.go"},
  163. dto.TemplateInfo{"dao.tpl", "modules/" + codeBody.ModuleName + "/dao/", utils.Camel2Case(codeBody.ClassNameCamel) + "_dao.go"},
  164. dto.TemplateInfo{"service.tpl", "modules/" + codeBody.ModuleName + "/service/", utils.Camel2Case(codeBody.ClassNameCamel) + "_service.go"},
  165. dto.TemplateInfo{"api.tpl", "modules/" + codeBody.ModuleName + "/api/v1/admin/", utils.Camel2Case(codeBody.ClassNameCamel) + "_api.go"},
  166. dto.TemplateInfo{"router.tpl", "modules/" + codeBody.ModuleName + "/router/admin/" + codeBody.ModuleName + "/", utils.Camel2Case(codeBody.ClassNameCamel) + "_router.go"}}
  167. genDir := "./temporary/code/go/"
  168. tplDir := "./resources/template/code/go/"
  169. for _, value := range tpls {
  170. t, err := template.New(value.Name).Funcs(template.FuncMap{
  171. "htmlSafe": func(html string) template.HTML {
  172. return template.HTML(html)
  173. },
  174. "toLower": func(html string) string {
  175. return strings.ToLower(html)
  176. },
  177. "toUpper": func(html string) string {
  178. return utils.Ucfirst(html)
  179. },
  180. "isLast": func(i, size int) bool { return i == size-1 },
  181. }).ParseFiles(tplDir + value.Name)
  182. if err != nil {
  183. fmt.Println("create template failed, err:", err)
  184. return
  185. }
  186. t.Execute(os.Stdout, codeBody)
  187. if _, err := os.Stat(genDir + value.Dir); os.IsNotExist(err) {
  188. // mkdir 创建目录,mkdirAll 可创建多层级目录
  189. os.MkdirAll(genDir+value.Dir, os.ModePerm)
  190. }
  191. f, err := os.Create(genDir + value.Dir + value.GenName)
  192. if err != nil {
  193. log.Println("create file: ", err)
  194. return
  195. }
  196. err = t.Execute(f, codeBody)
  197. if err != nil {
  198. log.Print("execute: ", err)
  199. return
  200. }
  201. f.Close()
  202. }
  203. //生成前端
  204. viwTpls := [3]dto.TemplateInfo{
  205. dto.TemplateInfo{"index.tpl", path.Join([]string{"src/views", codeBody.ModuleName,
  206. utils.Camel2Middle(codeBody.ClassNameCamel)}...), "index.vue"},
  207. dto.TemplateInfo{"edit.tpl", path.Join([]string{"src/views", codeBody.ModuleName,
  208. utils.Camel2Middle(codeBody.ClassNameCamel)}...), codeBody.ClassNameUpper + "Form.vue"},
  209. dto.TemplateInfo{"js.tpl", path.Join([]string{"src/api", codeBody.ModuleName, utils.Camel2Middle(codeBody.ClassNameCamel)}...),
  210. "index.ts"}}
  211. genDir = "./temporary/code/view/"
  212. tplDir = "./resources/template/code/vue3/"
  213. for _, value := range viwTpls {
  214. //t, err := template.New("index.tpl").Delims("{[", "]}").ParseFiles(tplDir + value.Name)
  215. t, err := template.New(value.Name).Delims("{[", "]}").Funcs(template.FuncMap{
  216. "htmlSafe": func(html string) template.HTML {
  217. return template.HTML(html)
  218. },
  219. "toLower": func(html string) string {
  220. return strings.ToLower(html)
  221. },
  222. "toMiddle": func(html string) string {
  223. return utils.Camel2Middle(html)
  224. },
  225. "toUpper": func(html string) string {
  226. return utils.Ucfirst(html)
  227. },
  228. "isLast": func(i, size int) bool { return i == size-1 },
  229. }).ParseFiles(tplDir + value.Name)
  230. if err != nil {
  231. fmt.Println("create template failed, err:", err)
  232. return
  233. }
  234. t.Execute(os.Stdout, codeBody)
  235. if _, err := os.Stat(genDir + value.Dir); os.IsNotExist(err) {
  236. // mkdir 创建目录,mkdirAll 可创建多层级目录
  237. os.MkdirAll(genDir+value.Dir, os.ModePerm)
  238. }
  239. f, err := os.Create(path.Join([]string{genDir, value.Dir, value.GenName}...))
  240. if err != nil {
  241. log.Println("create file: ", err)
  242. return
  243. }
  244. err = t.ExecuteTemplate(f, value.Name, codeBody)
  245. if err != nil {
  246. log.Print("execute: ", err)
  247. return
  248. }
  249. f.Close()
  250. }
  251. if codeBody.GenType == 1 {
  252. file.Copy(genDir, "yudao-ui/")
  253. file.Copy("./temporary/code/go/", "./")
  254. file.SearchAndWriteInfConst("./router/admin/router.go", "//初始化"+codeBody.FunctionName+"路由", "a."+utils.Ucfirst(codeBody.ModuleName)+".InitRouter(v1Router)", "//初始化路由结束")
  255. }
  256. c.Ok()
  257. }