package controllers import ( "annual-lottery/utils" "bytes" "errors" "reflect" "strconv" "time" "github.com/astaxie/beego" "net/http" "net/url" ) //Message api统一的返回消息格式 type Message struct { Code int `json:"code"` Message interface{} `json:"message"` } //BaseController 基础controller type BaseController struct { beego.Controller } const ( SESSION_USER = "h5.user" PAGENUM = 10 LISTPAGENUM = 20 ) // BaseControllerInterface 项目约定的 Controller 须满足的接口 type BaseControllerInterface interface { Constructor() } //Prepare 继承beego的 func (c *BaseController) Prepare() { // 路由对应的实际 Controller 初始化 c.initController() } // ResponseJson 自定义的JSON返回 func (c *BaseController) ResponseJson(msg interface{}, code ...int) { status := http.StatusOK if len(code) > 0 { status = code[0] } if reflect.ValueOf(msg).Type().String() == "*errors.errorString" { err := msg.(error) if status == http.StatusOK { status = http.StatusInternalServerError } c.Data["json"] = Message{status, err.Error()} } else { c.Data["json"] = Message{status, msg} } c.ServeJSON() c.StopRun() } // initAppController 执行当前路由请求对应的 Controller 初始化 func (c *BaseController) initController() { if ctrl, ok := c.AppController.(BaseControllerInterface); ok { ctrl.Constructor() } } // UploadFile 文件上传 // @router /file [post] func (c *BaseController) UploadFile() { f, h, err := c.GetFile("file") if err != nil { beego.Error("获取上传文件失败,", err) c.ResponseJson("获取上传文件失败") } defer f.Close() // 出现并发问题的概率忽略 pre := strconv.Itoa(time.Now().Nanosecond()) fname := pre + "-" + h.Filename fpath := "/upload/" + pre + "-" + h.Filename if err := c.SaveToFile("file", "."+fpath); err != nil { beego.Error("转储上传文件失败,", err) c.ResponseJson("转储上传文件失败") } c.ResponseJson(map[string]interface{}{ "name": fname, "url": fpath, }) } // SaveToExcel 保存文件到 excel // 文件不落地, 对内存开销比较大, 如果文件过大, 服务可能会崩掉 func (c *BaseController) SaveToExcel(fn string, excel *utils.TinyXLSXEngine) { var buf bytes.Buffer if err := excel.Write(&buf); err != nil { beego.Error("写 xlsx buffer 失败: " + err.Error()) c.ResponseJson(errors.New("生成 excel 异常, 请重试")) } c.Ctx.Output.Header("Content-Disposition", "attachment; filename="+url.QueryEscape(fn)) c.Ctx.Output.Header("Content-Description", "File Transfer") c.Ctx.Output.ContentType(".xlsx") c.Ctx.Output.Header("Content-Transfer-Encoding", "binary") c.Ctx.Output.Header("Expires", "0") c.Ctx.Output.Header("Cache-Control", "must-revalidate") c.Ctx.Output.Header("Pragma", "public") r := bytes.NewReader(buf.Bytes()) http.ServeContent(c.Ctx.ResponseWriter, c.Ctx.Request, fn, time.Now().Local(), r) c.StopRun() } func (c *BaseController) Index() { c.TplName = "index.html" // c.EnableRender = true c.Render() }