94 lines
1.8 KiB
Go
94 lines
1.8 KiB
Go
package fileutil
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"image"
|
|
"image/gif"
|
|
"image/jpeg"
|
|
"image/png"
|
|
"io"
|
|
"os"
|
|
"path"
|
|
"time"
|
|
|
|
nanoId "github.com/matoous/go-nanoid"
|
|
)
|
|
|
|
var (
|
|
// 图片最大数量
|
|
MaxImageSize = 10 << 20
|
|
ErrUnsupportedFileFormat = errors.New("图片格式不支持")
|
|
ErrFileStorePath = errors.New("文件存储路径异常")
|
|
ErrFileGenerateName = errors.New("文件名称生成异常")
|
|
ErrFileSaveFailed = errors.New("文件保存失败")
|
|
)
|
|
|
|
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 Mkdir(path string) error {
|
|
return os.MkdirAll(path, os.ModePerm)
|
|
}
|
|
|
|
func UploadImage(r io.Reader) (string, error) {
|
|
img, format, err := image.Decode(r)
|
|
if err != nil {
|
|
return "", fmt.Errorf("读取图片错误")
|
|
}
|
|
if errors.Is(err, image.ErrFormat) {
|
|
return "", ErrUnsupportedFileFormat
|
|
}
|
|
if format != "png" && format != "jpeg" && format != "gif" {
|
|
return "", ErrUnsupportedFileFormat
|
|
}
|
|
|
|
// 存放目录
|
|
curTime := time.Now()
|
|
dir := path.Join("upload", "imgs", curTime.Format("2006"), curTime.Format("01"), curTime.Format("02"))
|
|
exist, _ := PathExists(dir)
|
|
if !exist {
|
|
err := Mkdir(dir)
|
|
if err != nil {
|
|
return "", ErrFileStorePath
|
|
}
|
|
}
|
|
|
|
filename, err := nanoId.Nanoid()
|
|
if err != nil {
|
|
return "", ErrFileGenerateName
|
|
}
|
|
|
|
filePath := path.Join("", dir, filename+"."+format)
|
|
f, err := os.Create(filePath)
|
|
if err != nil {
|
|
return "", ErrFileStorePath
|
|
}
|
|
defer func(f *os.File) {
|
|
_ = f.Close()
|
|
}(f)
|
|
|
|
var e error
|
|
switch format {
|
|
case "png":
|
|
e = png.Encode(f, img)
|
|
case "jpeg":
|
|
e = jpeg.Encode(f, img, nil)
|
|
case "gif":
|
|
e = gif.Encode(f, img, nil)
|
|
}
|
|
if e != nil {
|
|
return "", ErrFileSaveFailed
|
|
}
|
|
|
|
return "/" + filePath, nil
|
|
}
|