package api import ( "crypto/md5" "encoding/hex" "errors" "fmt" "image" "image/gif" "image/jpeg" "image/png" "io" "mime/multipart" "net/http" "os" "path" "path/filepath" "strconv" "strings" "tmr-watch/conf/setting" "tmr-watch/http/handle/restful" "tmr-watch/pkg/app" "tmr-watch/pkg/e" "tmr-watch/pkg/logging" "github.com/astaxie/beego/logs" "github.com/axetroy/go-fs" "github.com/gin-gonic/gin" "github.com/nfnt/resize" "github.com/tealeg/xlsx" ) // 支持的图片后缀名 var supportImageExtNames = []string{".jpg", ".jpeg", ".png", ".ico", ".svg", ".bmp", ".gif"} /** check a file is a image or not */ func isImage(extName string) bool { for i := 0; i < len(supportImageExtNames); i++ { if supportImageExtNames[i] == extName { return true } } return false } /** Handler the parse error */ func parseFormFail(context *gin.Context) { context.JSON(http.StatusBadRequest, gin.H{ "msg": "fail", "message": "Can not parse form", }) } /** Upload file handler */ func UploadFile(context *gin.Context) { appG := app.Gin{C: context} dictId := context.Param("id") dictName := context.Param("name") logging.Info("UploadFile ", context.Keys, dictId, dictName) var ( isSupportFile bool maxUploadSize = setting.AppSetting.FileMaxSize // 最大上传大小 allowTypes = setting.AppSetting.FileAllowType // 可上传的文件类型 distPath string // 最终的输出目录 err error file *multipart.FileHeader src multipart.File dist *os.File ) // Source if file, err = context.FormFile("file"); err != nil { parseFormFail(context) return } sqlname := context.GetHeader("optname") extname := path.Ext(file.Filename) if len(allowTypes) != 0 { for i := 0; i < len(allowTypes); i++ { if allowTypes[i] == extname { isSupportFile = true break } } if isSupportFile == false { context.JSON(http.StatusBadRequest, gin.H{ "message": "不支持的文件类型: " + extname, }) return } } if file.Size > int64(maxUploadSize) { context.JSON(http.StatusBadRequest, gin.H{ "message": "上传文件太大, 最大限制为(byte): " + strconv.Itoa(int(maxUploadSize)), }) return } if src, err = file.Open(); err != nil { // open the file fail... } defer src.Close() hash := md5.New() io.Copy(hash, src) md5string := hex.EncodeToString(hash.Sum([]byte(""))) fileName := md5string + extname // Destination filePath := setting.CurrentPath + setting.AppSetting.FileSavePath + dictName + "/" err = PathCheck(filePath) //检查路径并创建 if err != nil { fmt.Println("PathCheck err", err) } distPath = path.Join(filePath, fileName) if dist, err = os.Create(distPath); err != nil { fmt.Println("Create err", err) } defer dist.Close() //distPath = setting.CurrentPath + setting.AppSetting.FileSavePath +"/"+ fileName if dist, err = os.Create(distPath); err != nil { // create dist file fail... } defer dist.Close() // FIXME: open 2 times if src, err = file.Open(); err != nil { // } // Copy io.Copy(dist, src) var execresult interface{} params := context.Request.Form if sqlname != "" { sql, p := restful.GetSqlByNameDB(sqlname) //todo insertcustomdoc if sql != "" { s_params := make([]interface{}, 0) paramslist := strings.Split(p, ",") if len(paramslist) > 0 && p != "" { for _, value := range paramslist { fmt.Println("s_params value", s_params, value) if strings.ToLower(strings.Trim(value, " ")) == "username" { //picpath, picname, username, newpicname tempv := params.Get("jwt_username") s_params = append(s_params, tempv) } else if strings.ToLower(strings.Trim(value, " ")) == "docname" { s_params = append(s_params, file.Filename) } else if strings.ToLower(strings.Trim(value, " ")) == "newdocname" { s_params = append(s_params, fileName) } else if strings.ToLower(strings.Trim(value, " ")) == "docpath" { s_params = append(s_params, dictName) // } else if strings.ToLower(strings.Trim(value, " ")) == "dictid" { s_params = append(s_params, dictId) // fmt.Println("s_params", s_params, dictId) } else if strings.ToLower(strings.Trim(value, " ")) == "filesize" { s_params = append(s_params, file.Size) // } else { s_params = append(s_params, params.Get(strings.Trim(value, " "))) } } } execresult, err = execDataBySql(sql, s_params) if err != nil { fmt.Println("execDataBySql err", err) appG.Response(http.StatusOK, e.ERROR, err.Error()) } } } context.JSON(http.StatusOK, gin.H{ "hash": md5string, "filename": fileName, "origin": file.Filename, "size": file.Size, "execresult": execresult, }) } /** Upload image handler */ func UploaderImage(context *gin.Context) { logging.Info("UploaderImage ", context.Keys) var ( maxUploadSize = setting.AppSetting.ImageMaxSize // 最大上传大小 distPath string // 最终的输出目录 err error file *multipart.FileHeader src multipart.File dist *os.File ) // Source if file, err = context.FormFile("file"); err != nil { parseFormFail(context) return } sqlname := context.GetHeader("optname") extname := strings.ToLower(path.Ext(file.Filename)) if isImage(extname) == false { context.JSON(http.StatusBadRequest, gin.H{ "message": "不支持的上传文件类型: " + extname, }) return } if file.Size > int64(maxUploadSize) { context.JSON(http.StatusBadRequest, gin.H{ "message": "上传文件太大, 最大文件大小限制为(byte): " + strconv.Itoa(int(maxUploadSize)), }) return } if src, err = file.Open(); err != nil { } defer src.Close() hash := md5.New() io.Copy(hash, src) md5string := hex.EncodeToString(hash.Sum([]byte(""))) fileName := md5string + extname //savePathDir := setting.CurrentPath+setting.AppSetting.ImageSavePath+fileName+"/" //_,err = os.Stat(savePathDir) //if err == nil { // fmt.Println(err)//todo 错误处理 //} //if os.IsNotExist(err) { // err:=os.Mkdir(setting.CurrentPath+setting.AppSetting.ImageSavePath+fileName,os.ModePerm) // if err!=nil{ // fmt.Println(err) // }//目录不存在则创建 //} // Destination picPath := setting.CurrentPath + setting.AppSetting.ImageSavePath + sqlname + "/" err = PathCheck(picPath) //检查路径并创建 if err != nil { fmt.Println("PathCheck err", err) } distPath = path.Join(picPath, fileName) if dist, err = os.Create(distPath); err != nil { fmt.Println("Create err", err) } defer dist.Close() // FIXME: open 2 times if src, err = file.Open(); err != nil { // } defer src.Close() // Copy io.Copy(dist, src) // 压缩缩略图 // 不管成功与否,都会进行下一步的返回 if _, err := thumbnailify(distPath, sqlname); err != nil { logging.Error("thumbnailify_err", err) picThumbnailPath := setting.CurrentPath + setting.AppSetting.ThumbnailSavePath + sqlname + "/" println(picThumbnailPath) err = PathCheck(picThumbnailPath) //检查路径并创建 distThumbnailPath := path.Join(picThumbnailPath, fileName) println(distThumbnailPath) distThumbnail, err := os.Create(distThumbnailPath) if err != nil { fmt.Println("CreateThumbnail err", err) } srcThumbnail, err := file.Open() if err != nil { // } io.Copy(distThumbnail, srcThumbnail) distThumbnail.Close() src.Close() } var execresult interface{} params := context.Request.Form if sqlname != "" { sql, p := restful.GetSqlByNameDB(sqlname) if sql != "" { s_params := make([]interface{}, 0) paramslist := strings.Split(p, ",") if len(paramslist) > 0 && p != "" { for _, value := range paramslist { if strings.ToLower(strings.Trim(value, " ")) == "username" { //picpath, picname, username, newpicname tempv := params.Get("jwt_username") s_params = append(s_params, tempv) } else if strings.ToLower(strings.Trim(value, " ")) == "picname" { s_params = append(s_params, file.Filename) } else if strings.ToLower(strings.Trim(value, " ")) == "newpicname" { s_params = append(s_params, fileName) } else if strings.ToLower(strings.Trim(value, " ")) == "picpath" { s_params = append(s_params, sqlname) //全路径加文件名 } else { s_params = append(s_params, params.Get(strings.Trim(value, " "))) } } } execresult, err = execDataBySql(sql, s_params) if err != nil { fmt.Println("execDataBySql err", err) } } } context.JSON(http.StatusOK, gin.H{ "hash": md5string, "filename": fileName, "origin": file.Filename, "size": file.Size, "execresult": execresult, }) } /** Upload image handler */ func UploaderTmrImage(context *gin.Context) { logging.Info("UploaderTmrImage ", context.Keys) var ( maxUploadSize = setting.AppSetting.ImageMaxSize // 最大上传大小 distPath string // 最终的输出目录 err error file *multipart.FileHeader src multipart.File dist *os.File ) // Source if file, err = context.FormFile("file"); err != nil { parseFormFail(context) return } pastureid := context.GetHeader("pastureid") //牧场id projuctid := context.GetHeader("projuctid") // 主计划id pfid := context.GetHeader("pfid") // 配方id optid := context.GetHeader("optid") //子计划id catchtime := context.GetHeader("catchtime") // 捕获时间 picclass := context.GetHeader("picclass") // 图片分类 extname := strings.ToLower(path.Ext(file.Filename)) if isImage(extname) == false { context.JSON(http.StatusBadRequest, gin.H{ "msg": "fail", "message": "不支持的上传文件类型: " + extname, }) return } if file.Size > int64(maxUploadSize) { context.JSON(http.StatusBadRequest, gin.H{ "msg": "fail", "message": "上传文件太大, 最大文件大小限制为(byte): " + strconv.Itoa(int(maxUploadSize)), }) return } if src, err = file.Open(); err != nil { } defer src.Close() hash := md5.New() io.Copy(hash, src) md5string := hex.EncodeToString(hash.Sum([]byte(""))) fileName := md5string + extname //savePathDir := setting.CurrentPath+setting.AppSetting.ImageSavePath+fileName+"/" //_,err = os.Stat(savePathDir) //if err == nil { // fmt.Println(err)//todo 错误处理 //} //if os.IsNotExist(err) { // err:=os.Mkdir(setting.CurrentPath+setting.AppSetting.ImageSavePath+fileName,os.ModePerm) // if err!=nil{ // fmt.Println(err) // }//目录不存在则创建 //} // Destination picPath := setting.CurrentPath + setting.AppSetting.ImageSavePath + projuctid + "/" err = PathCheck(picPath) //检查路径并创建 if err != nil { fmt.Println("PathCheck err", err) } distPath = path.Join(picPath, fileName) if dist, err = os.Create(distPath); err != nil { fmt.Println("Create err", err) } defer dist.Close() // FIXME: open 2 times if src, err = file.Open(); err != nil { // } defer src.Close() // Copy io.Copy(dist, src) // 压缩缩略图 // 不管成功与否,都会进行下一步的返回 if _, err := thumbnailify(distPath, projuctid); err != nil { logging.Error("thumbnailify_err", err) picThumbnailPath := setting.CurrentPath + setting.AppSetting.ThumbnailSavePath + projuctid + "/" println(picThumbnailPath) err = PathCheck(picThumbnailPath) //检查路径并创建 distThumbnailPath := path.Join(picThumbnailPath, fileName) println(distThumbnailPath) distThumbnail, err := os.Create(distThumbnailPath) if err != nil { fmt.Println("CreateThumbnail err", err) } srcThumbnail, err := file.Open() if err != nil { // } io.Copy(distThumbnail, srcThumbnail) distThumbnail.Close() src.Close() } var execresult interface{} params := context.Request.Form sqlname := "insertcustompic" if sqlname != "" { sql, p := restful.GetSqlByNameDB(sqlname) if sql != "" { s_params := make([]interface{}, 0) paramslist := strings.Split(p, ",") if len(paramslist) > 0 && p != "" { for _, value := range paramslist { switch strings.ToLower(strings.Trim(value, " ")) { case "username": tempv := params.Get("jwt_username") s_params = append(s_params, tempv) case "picname": s_params = append(s_params, file.Filename) case "newpicname": s_params = append(s_params, fileName) case "picpath": s_params = append(s_params, projuctid) case "pastureid": s_params = append(s_params, pastureid) case "projuctid": s_params = append(s_params, projuctid) case "pfid": s_params = append(s_params, pfid) case "optid": s_params = append(s_params, optid) case "catchtime": s_params = append(s_params, catchtime) case "picclass": s_params = append(s_params, picclass) default: s_params = append(s_params, params.Get(strings.Trim(value, " "))) } } } execresult, err = execDataBySql(sql, s_params) if err != nil { fmt.Println("execDataBySql err", err) } } } context.JSON(http.StatusOK, gin.H{ "msg": "ok", "hash": md5string, "filename": fileName, "origin": file.Filename, "size": file.Size, "execresult": execresult, }) } /** Get file raw */ func GetFileRaw(context *gin.Context) { filename := context.Param("filename") logging.Info("GetFileRaw ", context.Keys, filename) filePath := path.Join(setting.CurrentPath, setting.AppSetting.FileSavePath, filename) if isExistFile := fs.PathExists(filePath); isExistFile == false { // if the path not found http.NotFound(context.Writer, context.Request) return } http.ServeFile(context.Writer, context.Request, filePath) } /** Download a file */ func DownloadFile(context *gin.Context) { filename := context.Param("filename") logging.Info("DownloadFile ", context.Keys, filename) eqpic, _ := restful.Engine.SQL("SELECT * FROM eq_doc where id = ? ", filename).QueryString() if eqpic == nil { http.NotFound(context.Writer, context.Request) return } originFilePath := path.Join(setting.CurrentPath, setting.AppSetting.FileSavePath, eqpic[0]["docpath"], eqpic[0]["newdocname"]) if fs.PathExists(originFilePath) == false { // if the path not found http.NotFound(context.Writer, context.Request) return } http.ServeFile(context.Writer, context.Request, originFilePath) } /** Get Origin image */ func GetOriginImage(context *gin.Context) { //appG := app.Gin{C: context} filename := context.Param("filename") logging.Info("GetOriginImage ", context.Keys, filename) eqpic, _ := restful.Engine.SQL("SELECT * FROM eq_pic where id = ? ", filename).QueryString() if eqpic == nil { http.NotFound(context.Writer, context.Request) return } originImagePath := path.Join(setting.CurrentPath, setting.AppSetting.ImageSavePath, eqpic[0]["picpath"], eqpic[0]["newpicname"]) if fs.PathExists(originImagePath) == false { // if the path not found http.NotFound(context.Writer, context.Request) return } http.ServeFile(context.Writer, context.Request, originImagePath) //appG.Response(http.StatusOK, e.SUCCESS, eqpic[0]["picname"]) } /** Get thumbnail image */ func GetThumbnailImage(context *gin.Context) { filename := context.Param("filename") logging.Info("GetThumbnailImage ", context.Keys, filename) eqpic, _ := restful.Engine.SQL("SELECT * FROM eq_pic where id = ? ", filename).QueryString() if eqpic == nil { http.NotFound(context.Writer, context.Request) return } thumbnailImagePath := path.Join(setting.CurrentPath, setting.AppSetting.ThumbnailSavePath, eqpic[0]["picpath"], eqpic[0]["newpicname"]) originImagePath := path.Join(setting.CurrentPath, setting.AppSetting.ImageSavePath, filename) if fs.PathExists(thumbnailImagePath) == false { // if thumbnail image not exist, try to get origin image if fs.PathExists(originImagePath) == true { http.ServeFile(context.Writer, context.Request, originImagePath) return } // if the path not found http.NotFound(context.Writer, context.Request) return } http.ServeFile(context.Writer, context.Request, thumbnailImagePath) } /** Generate thumbnail */ func thumbnailify(imagePath, subdirectory string) (outputPath string, err error) { var ( file *os.File img image.Image ) Filename := strings.ToLower(path.Base(imagePath)) extname := strings.ToLower(path.Ext(imagePath)) outputPath = setting.CurrentPath + setting.AppSetting.ThumbnailSavePath + subdirectory + "/" + Filename err = PathCheck(setting.CurrentPath + setting.AppSetting.ThumbnailSavePath + subdirectory) if err != nil { fmt.Println("thumbnailify PathCheck err", err) } // 读取文件 if file, err = os.Open(imagePath); err != nil { return } defer file.Close() // decode jpeg into image.Image switch extname { case ".jpg", ".jpeg": img, err = jpeg.Decode(file) break case ".png": img, err = png.Decode(file) break case ".gif": img, err = gif.Decode(file) break default: err = errors.New("Unsupport file type" + extname) return } if img == nil { err = errors.New("Generate thumbnail fail...") return } m := resize.Thumbnail(uint(setting.AppSetting.ThumbnailMaxWidth), uint(setting.AppSetting.ThumbnailMaxHeight), img, resize.Lanczos3) out, err := os.Create(outputPath) if err != nil { return } defer out.Close() // write new image to file //decode jpeg/png/gif into image.Image switch extname { case ".jpg", ".jpeg": jpeg.Encode(out, m, nil) break case ".png": png.Encode(out, m) break case ".gif": gif.Encode(out, m, nil) break default: err = errors.New("Unsupport file type" + extname) return } return } func UploadFiles(c *gin.Context) { logging.Info("UploadFiles ", c.Keys) appG := app.Gin{C: c} err := c.Request.ParseMultipartForm(200000) if err != nil { appG.Response(http.StatusOK, e.ERROR_IMPORT_FAIL, err) return } // 获取表单 form := c.Request.MultipartForm // 获取参数upload后面的多个文件名,存放到数组files里面, files := form.File["upload"] // 遍历数组,每取出一个file就拷贝一次 for i, _ := range files { file, err := files[i].Open() defer file.Close() if err != nil { appG.Response(http.StatusOK, e.ERROR_IMPORT_FAIL, err) return } fileName := files[i].Filename fmt.Println(fileName) out, err := os.Create(fileName) defer out.Close() if err != nil { appG.Response(http.StatusOK, e.ERROR_IMPORT_FAIL, err) return } _, err = io.Copy(out, file) if err != nil { appG.Response(http.StatusOK, e.ERROR_IMPORT_FAIL, err) return } appG.Response(http.StatusOK, e.SUCCESS, "upload successful \n") } } func PathCheck(path string) (err error) { b, err := PathExists(path) if err != nil { fmt.Println("exist err", err) } if !b { fmt.Println(path, " 目录不存在,重新创建") err = os.Mkdir(path, 0777) if err != nil { fmt.Println("Mkdir err", err) } } return } func PathExists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { return true, nil } if os.IsNotExist(err) { return false, nil } return false, err } func GetBarfeedremainExcel(c *gin.Context) { var file *xlsx.File var sheet *xlsx.Sheet var row *xlsx.Row var cell *xlsx.Cell style := xlsx.NewStyle() style.ApplyBorder = true border := *xlsx.NewBorder("thin", "thin", "thin", "thin") style.Border = border style.Font.Size = 11 style.Alignment = xlsx.Alignment{ Horizontal: "center", Vertical: "center", WrapText: true, // ShrinkToFit: true, } style.ApplyBorder = true file = xlsx.NewFile() sheet, _ = file.AddSheet("Sheet1") // row = sheet.AddRow() // cell = row.AddCell() row = sheet.AddRow() cell = row.AddCell() cell.Value = "栏舍名称" // cell.Merge(0, 1) cell.SetStyle(style) cell = row.AddCell() cell.SetValue("剩料量(kg)") cell.SetStyle(style) cell = row.AddCell() cell.SetValue("干物质") cell.SetStyle(style) cell = row.AddCell() cell.SetValue("班次(第一班/第二班/第三班)") cell.SetStyle(style) cell = row.AddCell() cell.SetValue("收集时间") cell.SetStyle(style) cell = row.AddCell() cell.SetValue("操作人") cell.SetStyle(style) cell = row.AddCell() tx := restful.Engine.NewSession() defer tx.Close() dataList, err := tx.SQL(`select bname from bar where pastureid = (select column_default as pastureid from information_schema.COLUMNS WHERE table_name = 'recweight' AND table_schema = ? AND column_name = 'pastureid') order by sort ,id`, setting.DatabaseSetting.Name).Query().List() if err != nil { logs.Error("CronScheduled-error-1:", err) return } for _, data := range dataList { row = sheet.AddRow() cell = row.AddCell() cell.SetValue(data["bname"]) cell.SetStyle(style) } c.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") c.Header("Content-Disposition", "attachment; filename="+"栏舍剩料记录导入模板.xlsx") c.Header("Content-Transfer-Encoding", "binary") _ = file.Write(c.Writer) } func UploadFile1(c *gin.Context) { appG := app.Gin{C: c} pid := c.PostForm("pid") sort := c.PostForm("sort") isStart := c.PostForm("isStart") file, err := appG.C.FormFile("file") if err != nil { logs.Error(err) appG.Response(http.StatusInternalServerError, e.ERROR, err) return } tx := restful.Engine.NewSession() defer tx.Close() fileInfoList, err := tx.SQL(` select startpicture,endpicture from downloadplandtl1_exec where pid = ? and sort = ? `, pid, sort).Query().List() if err != nil { logs.Error(err) appG.Response(http.StatusInternalServerError, e.ERROR, err) return } if len(fileInfoList) > 0 { filepath := "" for _, fileinfo := range fileInfoList { if isStart == "1" { if _, ok := fileinfo["startpicture"]; ok { filepath = fileinfo["startpicture"].(string) } } else { if _, ok := fileinfo["endpicture"]; ok { filepath = fileinfo["endpicture"].(string) } } } os.Remove(filepath) } basePath := "uploads/image/" filename := basePath + filepath.Base(file.Filename) if err := appG.C.SaveUploadedFile(file, filename); err != nil { logs.Error(err) appG.Response(http.StatusInternalServerError, e.ERROR, err) return } // filename = basePath + filepath.Base(file.Filename) if isStart == "1" { _, err = tx.SQL(` update downloadplandtl1_exec set startpicture = ? where pid = ? and sort = ? `, filename, pid, sort).Execute() if err != nil { logs.Error(err) appG.Response(http.StatusInternalServerError, e.ERROR, err) return } } else { _, err = tx.SQL(` update downloadplandtl1_exec set endpicture = ? where pid = ? and sort = ? `, filename, pid, sort).Execute() if err != nil { logs.Error(err) appG.Response(http.StatusInternalServerError, e.ERROR, err) return } } appG.Response(http.StatusOK, e.SUCCESS, fmt.Sprintf("文件 %s 上传成功 ", file.Filename)) } // func DownloadFile1(c *gin.Context) { // appG := app.Gin{C: c} // dataByte, _ := ioutil.ReadAll(c.Request.Body) // parammaps := gofasion.NewFasion(string(dataByte)) // businessid := parammaps.Get("businessid").ValueStr() // tx := restful.Engine.NewSession() // defer tx.Close() // fileInfoList, err := tx.SQL(` select path from file where businessid = ? `, businessid).Query().List() // if err != nil { // logs.Error(err) // appG.Response(http.StatusInternalServerError, e.ERROR, err) // return // } // filepath := "" // for _, fileinfo := range fileInfoList { // filepath = fileinfo["path"].(string) // } // c.File(filepath) // }