gen_table.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. package admin
  2. import (
  3. "gfast/app/model/admin/gen_table"
  4. "gfast/app/service/admin/gen_service"
  5. "gfast/app/service/admin/user_service"
  6. "gfast/library/response"
  7. "github.com/gogf/gf/os/gmutex"
  8. "strings"
  9. "github.com/gogf/gf/encoding/gcompress"
  10. "github.com/gogf/gf/encoding/gjson"
  11. "github.com/gogf/gf/errors/gerror"
  12. "github.com/gogf/gf/frame/g"
  13. "github.com/gogf/gf/net/ghttp"
  14. "github.com/gogf/gf/os/gfile"
  15. "github.com/gogf/gf/os/gview"
  16. "github.com/gogf/gf/text/gregex"
  17. "github.com/gogf/gf/text/gstr"
  18. "github.com/gogf/gf/util/gconv"
  19. "github.com/gogf/gf/util/grand"
  20. "github.com/gogf/gf/util/gvalid"
  21. )
  22. type Gen struct{}
  23. var mu = gmutex.New()
  24. // @Summary 查询数据库列表
  25. // @Description 查询数据库列表
  26. // @Tags 系统工具
  27. // @Param data body gen_table.SelectPageReq true "data"
  28. // @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
  29. // @Router /system/tools/gen/dataList [get]
  30. // @Security
  31. func (c *Gen) DataList(r *ghttp.Request) {
  32. var req *gen_table.SelectPageReq
  33. //获取参数
  34. if err := r.Parse(&req); err != nil {
  35. response.FailJson(true, r, err.(*gvalid.Error).FirstString())
  36. }
  37. total, list, err := gen_service.SelectDbTableList(req)
  38. if err != nil {
  39. response.FailJson(true, r, err.Error())
  40. }
  41. response.SusJson(true, r, "ok", g.Map{
  42. "total": total,
  43. "list": list,
  44. })
  45. }
  46. // @Summary 表列表
  47. // @Description 表列表
  48. // @Tags 系统工具
  49. // @Param data body gen_table.SelectPageReq true "data"
  50. // @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
  51. // @Router /system/tools/gen/tableList [post]
  52. // @Security
  53. func (c *Gen) TableList(r *ghttp.Request) {
  54. var req *gen_table.SelectPageReq
  55. //获取参数
  56. if err := r.Parse(&req); err != nil {
  57. response.FailJson(true, r, err.(*gvalid.Error).FirstString())
  58. }
  59. total, list, err := gen_service.SelectListByPage(req)
  60. if err != nil {
  61. response.FailJson(true, r, err.Error())
  62. }
  63. response.SusJson(true, r, "ok", g.Map{
  64. "total": total,
  65. "list": list,
  66. })
  67. }
  68. // @Summary 导入表结构操作
  69. // @Description 导入表结构操作
  70. // @Tags 系统工具
  71. // @Param tables body string true "tables"
  72. // @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
  73. // @Router /system/tools/gen/importTableSave [post]
  74. // @Security
  75. func (c *Gen) ImportTableSave(r *ghttp.Request) {
  76. tables := r.GetString("tables")
  77. if tables == "" {
  78. response.FailJson(true, r, "请选择要导入的表格")
  79. }
  80. user := user_service.GetLoginAdminInfo(r)
  81. operName := user.UserName
  82. tableArr := strings.Split(tables, ",")
  83. tableList, err := gen_service.SelectDbTableListByNames(tableArr)
  84. if err != nil {
  85. response.FailJson(true, r, err.Error())
  86. }
  87. if tableList == nil {
  88. response.FailJson(true, r, "表信息不存在")
  89. }
  90. err = gen_service.ImportGenTable(tableList, operName)
  91. if err != nil {
  92. response.FailJson(true, r, err.Error())
  93. }
  94. response.SusJson(true, r, "导入数据表成功")
  95. }
  96. // @Summary 根据表格ID获取表格字段列表数据
  97. // @Description 根据表格ID获取表格字段列表数据
  98. // @Tags 系统工具
  99. // @Param tableId body integer true "tableId"
  100. // @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
  101. // @Router /system/tools/gen/columnList [post]
  102. // @Security
  103. func (c *Gen) ColumnList(r *ghttp.Request) {
  104. tableId := r.GetInt64("tableId")
  105. if tableId == 0 {
  106. response.FailJson(true, r, "参数错误")
  107. }
  108. list, err := gen_service.SelectGenTableColumnListByTableId(tableId)
  109. if err != nil {
  110. response.FailJson(true, r, err.Error())
  111. }
  112. var tableInfo *gen_table.Entity
  113. var tableMap g.Map
  114. tableInfo, err = gen_service.GetTableInfoByTableId(tableId)
  115. tableMap = gconv.Map(tableInfo)
  116. //如果是树表则设置树表配置
  117. if tableInfo != nil && tableInfo.TplCategory == "tree" {
  118. options := gjson.New(tableInfo.Options)
  119. tableMap["tree_code"] = options.Get("tree_code")
  120. tableMap["tree_parent_code"] = options.Get("tree_parent_code")
  121. tableMap["tree_name"] = options.Get("tree_name")
  122. }
  123. res := g.Map{
  124. "rows": list,
  125. "info": tableMap,
  126. }
  127. response.SusJson(true, r, "ok", res)
  128. }
  129. // @Summary 编辑表格信息
  130. // @Description 编辑表格信息
  131. // @Tags 系统工具
  132. // @Param data body gen_table.EditReq true "data"
  133. // @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
  134. // @Router /system/tools/gen/editSave [post]
  135. // @Security
  136. func (c *Gen) EditSave(r *ghttp.Request) {
  137. var req *gen_table.EditReq
  138. //获取参数
  139. if err := r.Parse(&req); err != nil {
  140. response.FailJson(true, r, err.(*gvalid.Error).FirstString())
  141. }
  142. userInfo := user_service.GetLoginAdminInfo(r)
  143. req.UserName = userInfo.UserName
  144. err := gen_service.SaveEdit(req)
  145. if err != nil {
  146. response.FailJson(true, r, err.Error())
  147. }
  148. response.SusJson(true, r, "设置成功")
  149. }
  150. // @Summary 删除表格数据
  151. // @Description 删除表格数据
  152. // @Tags 系统工具
  153. // @Param ids body integer true "ids[1,2,3...]"
  154. // @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
  155. // @Router /system/tools/gen/delete [delete]
  156. // @Security
  157. func (c *Gen) Delete(r *ghttp.Request) {
  158. ids := r.GetInts("ids")
  159. if len(ids) == 0 {
  160. response.FailJson(true, r, "参数错误")
  161. }
  162. err := gen_service.Delete(ids)
  163. if err != nil {
  164. response.FailJson(true, r, err.Error())
  165. }
  166. response.SusJson(true, r, "删除成功")
  167. }
  168. // @Summary 代码生成预览
  169. // @Description 代码生成预览
  170. // @Tags 系统工具
  171. // @Param tableId body integer true "tableId"
  172. // @Success 0 {object} response.Response "{"code": 200, "data": [...]}"
  173. // @Router /system/tools/gen/preview [post]
  174. // @Security
  175. func (c *Gen) Preview(r *ghttp.Request) {
  176. tableId := r.GetInt64("tableId")
  177. if tableId == 0 {
  178. response.FailJson(true, r, "参数错误")
  179. }
  180. data, _, err := c.genData(tableId)
  181. if err != nil {
  182. response.FailJson(true, r, err.Error())
  183. }
  184. response.SusJson(true, r, "ok", data)
  185. }
  186. //下载生成的代码
  187. func (c *Gen) BatchGenCode(r *ghttp.Request) {
  188. tableIds := r.GetString("tables")
  189. if tableIds == "" {
  190. response.FailJson(true, r, "请选择要生成的表")
  191. }
  192. ids := gstr.Split(tableIds, ",")
  193. dataFilePath := g.Cfg().GetString("adminInfo.dataDir")
  194. dataFileRange := grand.S(10)
  195. //生成文件
  196. for _, id := range ids {
  197. data, entity, err := c.genData(gconv.Int64(id))
  198. if err != nil {
  199. response.FailJson(true, r, err.Error())
  200. }
  201. pathMap := c.getPath(entity)
  202. for key, val := range data {
  203. switch key {
  204. case "vm/go/" + entity.BusinessName + "_controller.go.vm":
  205. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/go/"+pathMap["controller"], val)
  206. if err != nil {
  207. response.FailJson(true, r, err.Error())
  208. }
  209. case "vm/go/" + entity.BusinessName + "_service.go.vm":
  210. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/go/"+pathMap["service"], val)
  211. if err != nil {
  212. response.FailJson(true, r, err.Error())
  213. }
  214. case "vm/go/" + entity.BusinessName + "_model.go.vm":
  215. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/go/"+pathMap["gfgenModel"], val)
  216. if err != nil {
  217. response.FailJson(true, r, err.Error())
  218. }
  219. case "vm/go/" + entity.BusinessName + "_entity.go.vm":
  220. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/go/"+pathMap["gfgenEntity"], val)
  221. if err != nil {
  222. response.FailJson(true, r, err.Error())
  223. }
  224. case "vm/go/" + entity.BusinessName + ".go.vm":
  225. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/go/"+pathMap["model"], val)
  226. if err != nil {
  227. response.FailJson(true, r, err.Error())
  228. }
  229. case "vm/go/" + entity.BusinessName + "_route.go.vm":
  230. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/go/路由说明.txt", val)
  231. if err != nil {
  232. response.FailJson(true, r, err.Error())
  233. }
  234. case "vm/html/" + entity.BusinessName + "_api.js.vm":
  235. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/vue/"+pathMap["api"], val)
  236. if err != nil {
  237. response.FailJson(true, r, err.Error())
  238. }
  239. case "vm/html/" + entity.BusinessName + "_vue.js.vm":
  240. err = gfile.PutContents(dataFilePath+"/gen/"+dataFileRange+"/vue/"+pathMap["vue"], val)
  241. if err != nil {
  242. response.FailJson(true, r, err.Error())
  243. }
  244. }
  245. }
  246. }
  247. //打包
  248. err := gcompress.ZipPathWriter(dataFilePath+"/gen/"+dataFileRange, r.Response.Writer)
  249. if err != nil {
  250. response.FailJson(true, r, err.Error())
  251. }
  252. //删除生成的文件
  253. gfile.Remove(dataFilePath + "/gen/" + dataFileRange)
  254. //设置下载文件名
  255. r.Response.Header().Set("Content-Length", gconv.String(r.Response.BufferLength()))
  256. r.Response.Header().Set("Content-Type", "application/force-download")
  257. r.Response.Header().Set("Accept-Ranges", "bytes")
  258. r.Response.Header().Set("Content-Disposition", "attachment; filename=gfast.zip")
  259. r.Response.Buffer()
  260. }
  261. //获取生成文件的目录
  262. func (c *Gen) getPath(entity *gen_table.EntityExtend) g.MapStrStr {
  263. controller := "app/controller/" + entity.ModuleName + "/" + entity.ClassName + ".go"
  264. service := "app/service/" + entity.ModuleName + "/" + entity.BusinessName + "_service/" + entity.ClassName + ".go"
  265. model := "app/model/" + entity.ModuleName + "/" + entity.BusinessName + "/" + entity.ClassName + ".go"
  266. gfgenModel := "app/model/" + entity.ModuleName + "/" + entity.BusinessName + "/" + entity.ClassName + "_model.go"
  267. gfgenEntity := "app/model/" + entity.ModuleName + "/" + entity.BusinessName + "/" + entity.ClassName + "_entity.go"
  268. vue := "views/" + entity.ModuleName + "/" + entity.BusinessName + "/index.vue"
  269. api := "api/" + entity.ModuleName + "/" + entity.BusinessName + ".js"
  270. return g.MapStrStr{
  271. "controller": controller,
  272. "service": service,
  273. "model": model,
  274. "gfgenModel": gfgenModel,
  275. "gfgenEntity": gfgenEntity,
  276. "vue": vue,
  277. "api": api,
  278. }
  279. }
  280. //获取生成数据
  281. func (c *Gen) genData(tableId int64) (data g.MapStrStr, entity *gen_table.EntityExtend, err error) {
  282. entity, err = gen_service.SelectRecordById(tableId)
  283. if err != nil {
  284. return
  285. }
  286. if entity == nil {
  287. err = gerror.New("表格数据不存在")
  288. return
  289. }
  290. gen_service.SetPkColumn(entity, entity.Columns)
  291. controllerKey := "vm/go/" + entity.BusinessName + "_controller.go.vm"
  292. controllerValue := ""
  293. serviceKey := "vm/go/" + entity.BusinessName + "_service.go.vm"
  294. serviceValue := ""
  295. modelKey := "vm/go/" + entity.BusinessName + ".go.vm"
  296. modelValue := ""
  297. routeKey := "vm/go/" + entity.BusinessName + "_route.go.vm"
  298. routeValue := ""
  299. gfgenModelKey := "vm/go/" + entity.BusinessName + "_model.go.vm"
  300. gfgenModelValue := ""
  301. gfgenEntityKey := "vm/go/" + entity.BusinessName + "_entity.go.vm"
  302. gfgenEntityValue := ""
  303. apiJsKey := "vm/html/" + entity.BusinessName + "_api.js.vm"
  304. apiJsValue := ""
  305. vueKey := "vm/html/" + entity.BusinessName + "_vue.js.vm"
  306. vueValue := ""
  307. mu.Lock()
  308. view := gview.New()
  309. view.BindFuncMap(g.Map{
  310. "UcFirst": func(str string) string {
  311. return gstr.UcFirst(str)
  312. },
  313. "add": func(a, b int) int {
  314. return a + b
  315. },
  316. })
  317. view.SetConfigWithMap(g.Map{
  318. "Paths": []string{"template"},
  319. "Delimiters": []string{"${", "}"},
  320. })
  321. mu.Unlock()
  322. //树形菜单选项
  323. var options g.Map
  324. if entity.TplCategory == "tree" {
  325. options = gjson.New(entity.Options).ToMap()
  326. }
  327. var tmpController string
  328. if tmpController, err = view.Parse("vm/go/"+entity.TplCategory+"/controller.template", g.Map{"table": entity}); err == nil {
  329. controllerValue = tmpController
  330. } else {
  331. return
  332. }
  333. var tmpService string
  334. if tmpService, err = view.Parse("vm/go/"+entity.TplCategory+"/service.template", g.Map{"table": entity, "options": options}); err == nil {
  335. serviceValue = tmpService
  336. } else {
  337. return
  338. }
  339. var tmpModel string
  340. if tmpModel, err = view.Parse("vm/go/"+entity.TplCategory+"/model.template", g.Map{"table": entity}); err == nil {
  341. modelValue = tmpModel
  342. modelValue, err = c.trimBreak(modelValue)
  343. } else {
  344. return
  345. }
  346. var tmpJs string
  347. if tmpJs, err = view.Parse("vm/html/js.template", g.Map{"table": entity}); err == nil {
  348. apiJsValue = tmpJs
  349. } else {
  350. return
  351. }
  352. var tmpVue string
  353. if tmpVue, err = view.Parse("vm/html/vue_"+entity.TplCategory+".template", g.Map{"table": entity, "options": options}); err == nil {
  354. vueValue = tmpVue
  355. vueValue, err = c.trimBreak(vueValue)
  356. } else {
  357. return
  358. }
  359. var tmpRouter string
  360. if tmpRouter, err = view.Parse("vm/go/common/route.template", g.Map{"table": entity}); err == nil {
  361. routeValue = tmpRouter
  362. } else {
  363. return
  364. }
  365. var tmpGfModel string
  366. if tmpGfModel, err = view.Parse("vm/go/common/model.template", g.Map{"table": entity}); err == nil {
  367. gfgenModelValue = tmpGfModel
  368. } else {
  369. return
  370. }
  371. var tmpGfEntity string
  372. if tmpGfEntity, err = view.Parse("vm/go/common/entity.template", g.Map{"table": entity}); err == nil {
  373. gfgenEntityValue = tmpGfEntity
  374. } else {
  375. return
  376. }
  377. data = g.MapStrStr{
  378. routeKey: routeValue,
  379. gfgenModelKey: gfgenModelValue,
  380. gfgenEntityKey: gfgenEntityValue,
  381. modelKey: modelValue,
  382. serviceKey: serviceValue,
  383. controllerKey: controllerValue,
  384. apiJsKey: apiJsValue,
  385. vueKey: vueValue,
  386. }
  387. return
  388. }
  389. //剔除多余的换行
  390. func (c *Gen) trimBreak(str string) (s string, err error) {
  391. var b []byte
  392. if b, err = gregex.Replace("(([\\s\t]*)\r?\n){2,}", []byte("$2\n"), []byte(str)); err == nil {
  393. s = gconv.String(b)
  394. }
  395. return
  396. }