base.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. package controllers
  2. import (
  3. "annual-lottery/utils"
  4. "bytes"
  5. "errors"
  6. "reflect"
  7. "strconv"
  8. "time"
  9. "github.com/astaxie/beego"
  10. "net/http"
  11. "net/url"
  12. )
  13. //Message api统一的返回消息格式
  14. type Message struct {
  15. Code int `json:"code"`
  16. Message interface{} `json:"message"`
  17. }
  18. //BaseController 基础controller
  19. type BaseController struct {
  20. beego.Controller
  21. }
  22. const (
  23. SESSION_USER = "h5.user"
  24. PAGENUM = 10
  25. LISTPAGENUM = 20
  26. )
  27. // BaseControllerInterface 项目约定的 Controller 须满足的接口
  28. type BaseControllerInterface interface {
  29. Constructor()
  30. }
  31. //Prepare 继承beego的
  32. func (c *BaseController) Prepare() {
  33. // 路由对应的实际 Controller 初始化
  34. c.initController()
  35. }
  36. // ResponseJson 自定义的JSON返回
  37. func (c *BaseController) ResponseJson(msg interface{}, code ...int) {
  38. status := http.StatusOK
  39. if len(code) > 0 {
  40. status = code[0]
  41. }
  42. if reflect.ValueOf(msg).Type().String() == "*errors.errorString" {
  43. err := msg.(error)
  44. if status == http.StatusOK {
  45. status = http.StatusInternalServerError
  46. }
  47. c.Data["json"] = Message{status, err.Error()}
  48. } else {
  49. c.Data["json"] = Message{status, msg}
  50. }
  51. c.ServeJSON()
  52. c.StopRun()
  53. }
  54. // initAppController 执行当前路由请求对应的 Controller 初始化
  55. func (c *BaseController) initController() {
  56. if ctrl, ok := c.AppController.(BaseControllerInterface); ok {
  57. ctrl.Constructor()
  58. }
  59. }
  60. // UploadFile 文件上传
  61. // @router /file [post]
  62. func (c *BaseController) UploadFile() {
  63. f, h, err := c.GetFile("file")
  64. if err != nil {
  65. beego.Error("获取上传文件失败,", err)
  66. c.ResponseJson("获取上传文件失败")
  67. }
  68. defer f.Close()
  69. // 出现并发问题的概率忽略
  70. pre := strconv.Itoa(time.Now().Nanosecond())
  71. fname := pre + "-" + h.Filename
  72. fpath := "/upload/" + pre + "-" + h.Filename
  73. if err := c.SaveToFile("file", "."+fpath); err != nil {
  74. beego.Error("转储上传文件失败,", err)
  75. c.ResponseJson("转储上传文件失败")
  76. }
  77. c.ResponseJson(map[string]interface{}{
  78. "name": fname,
  79. "url": fpath,
  80. })
  81. }
  82. // SaveToExcel 保存文件到 excel
  83. // 文件不落地, 对内存开销比较大, 如果文件过大, 服务可能会崩掉
  84. func (c *BaseController) SaveToExcel(fn string, excel *utils.TinyXLSXEngine) {
  85. var buf bytes.Buffer
  86. if err := excel.Write(&buf); err != nil {
  87. beego.Error("写 xlsx buffer 失败: " + err.Error())
  88. c.ResponseJson(errors.New("生成 excel 异常, 请重试"))
  89. }
  90. c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(fn))
  91. c.Ctx.Output.Header("Content-Description", "File Transfer")
  92. c.Ctx.Output.ContentType(".xlsx")
  93. c.Ctx.Output.Header("Content-Transfer-Encoding", "binary")
  94. c.Ctx.Output.Header("Expires", "0")
  95. c.Ctx.Output.Header("Cache-Control", "must-revalidate")
  96. c.Ctx.Output.Header("Pragma", "public")
  97. r := bytes.NewReader(buf.Bytes())
  98. http.ServeContent(c.Ctx.ResponseWriter, c.Ctx.Request, fn, time.Now().Local(), r)
  99. c.StopRun()
  100. }
  101. func (c *BaseController) Index() {
  102. c.TplName = "index.html"
  103. // c.EnableRender = true
  104. c.Render()
  105. }