package utils import ( "encoding/base64" "errors" uuid "github.com/iris-contrib/go.uuid" "github.com/kataras/iris/v12" "io" "mime/multipart" "os" "path/filepath" "strings" "time" ) // client version and secret, it should be from client side const ( UploadDir string = "./public/upload/" UrlBase string = "/upload/" ) // DstFile 文件 type DstFile struct { Name string `json:"name"` Src string `json:"src"` } func UploadFile(ctx iris.Context) (*DstFile,error){ file ,info ,err := ctx.FormFile("uploadfile") if err != nil { return nil ,err } defer file.Close() oldFileName := info.Filename destFile, url := GenerateNewFileName(oldFileName) out, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE, 0666) if err != nil{ return nil, err } defer out.Close() _ ,err = io.Copy(out,file) if err != nil { return nil, err } outfile := &DstFile{Name: oldFileName ,Src:url } return outfile, nil } func UploadFileBase64(ctx iris.Context) (*DstFile,error){ base64StrRaw := ctx.FormValue("base64") if base64StrRaw == "" && len(base64StrRaw) <= 8 { return nil, errors.New("文件错误") } index := strings.Index(base64StrRaw, ";") base64Str := base64StrRaw[index+8:] destByte, err := base64.StdEncoding.DecodeString(base64Str) if err != nil { return nil, err } suffix := base64StrRaw[11:index] oldFileName := "old."+suffix destFile, url := GenerateNewFileName(oldFileName) out, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE, 0666) if err != nil{ return nil, err } defer out.Close() _ ,err = out.Write(destByte) if err != nil { return nil, err } outfile := &DstFile{Name: oldFileName ,Src:url } return outfile, nil } // UploadMultiFiles Upload Multi Files func UploadMultiFiles(ctx iris.Context)(int, []DstFile, error){ outFiles := []DstFile{} maxSize := ctx.Application().ConfigurationReadOnly().GetPostMaxMemory() err := ctx.Request().ParseMultipartForm(maxSize) if err != nil { return 0 , outFiles, err } form := ctx.Request().MultipartForm files := form.File["files[]"] count := len(files) failures := 0 dstIndex := 1 for _, file := range files { url, err := SaveUploadFile(file) if err != nil { failures++ }else{ out := DstFile{Name: file.Filename ,Src:url} outFiles = append(outFiles, out) dstIndex++ } } num := count - failures return num ,outFiles ,nil } func SaveUploadFile(fh *multipart.FileHeader)(string, error){ src ,err := fh.Open() if err != nil { return "" ,err } defer src.Close() oldFileName := fh.Filename srcFile, urlFile := GenerateNewFileName(oldFileName) out, err := os.OpenFile(srcFile ,os.O_WRONLY|os.O_CREATE ,os.FileMode(0666)) if err != nil { return "" ,err } defer out.Close() _, err = io.Copy(out, src) return urlFile, err } // BeforeSave Before Save func BeforeSave(ctx iris.Context ,file *multipart.FileHeader){ ip := ctx.RemoteAddr() ip = strings.Replace(ip ,"." ,"-" ,-1) ip = strings.Replace(ip ,":" ,"-" ,-1) file.Filename = ip + "-" + file.Filename } // CreateDateDir Create date directory func CreateDateDir() (srcPath, urlPath string) { folderName := time.Now().Format("20060102") src := filepath.Join(UploadDir, folderName) url := filepath.Join(UrlBase, folderName) _, err := os.Stat(srcPath) if os.IsNotExist(err ){ _ = os.Mkdir(src, os.ModePerm) _ = os.Chmod(src, os.ModePerm) } return src ,url } // GenerateNewFileName Generate new file name func GenerateNewFileName(oldFileName string) (srcPath, urlPath string) { u1, _ := uuid.NewV4() newFileName := u1.String() src , url := CreateDateDir() dotIndex := strings.LastIndex(oldFileName, ".") if dotIndex != -1 && dotIndex != 0 { newFileName += oldFileName[dotIndex:] } src = filepath.Join(src, newFileName) url = filepath.Join(url, newFileName) return src, url }