1 Star 1 Fork 1

xiaoyutab/xgotool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
upload.go 5.78 KB
一键复制 编辑 原始数据 按行查看 历史
xiaoyutab 提交于 2024-07-31 16:04 . 1
package xgotool
import (
"errors"
"io"
"mime/multipart"
"os"
"path"
"strings"
"gitee.com/xiaoyutab/xgotool/xnum"
"gitee.com/xiaoyutab/xgotool/xstring"
)
// 文件上传结构
type FileConfig struct {
SavePath string `json:"save_path"` // 保存目录,若结尾不为 `/` 会自动追加 `/` 进行间隔
SaveName string `json:"save_name"` // 保存文件名若无后缀则自动追加原后缀信息
UpImage bool `json:"up_image"` // 是否允许上传图片
UpDocument bool `json:"up_document"` // 是否允许上传文档
UpAudio bool `json:"up_audio"` // 是否允许上传音频
UpVideo bool `json:"up_video"` // 是否允许上传视频
UpConfig bool `json:"up_config"` // 是否允许上传配置文件
UpZip bool `json:"up_zip"` // 是否允许上传压缩包文件
UpOther bool `json:"up_other"` // 是否允许上传其他后缀文件
UpNone bool `json:"up_none"` // 是否允许无后缀文件上传
MaxSize int64 `json:"max_size"` // 上传文件的最大大小配置,单位:B,0表示不限制
IsImage bool `json:"is_image"` // 上传文件是图片 // 上传处理过程中会回写的变量
IsDocument bool `json:"is_document"` // 上传文件是文档 // 上传处理过程中会回写的变量
IsAudio bool `json:"is_audio"` // 上传文件是音频 // 上传处理过程中会回写的变量
IsVideo bool `json:"is_video"` // 上传文件是视频 // 上传处理过程中会回写的变量
IsConfig bool `json:"is_config"` // 上传文件是配置文件 // 上传处理过程中会回写的变量
IsZip bool `json:"is_zip"` // 上传文件是压缩包文件 // 上传处理过程中会回写的变量
IsOther bool `json:"is_other"` // 上传文件是其他后缀文件 // 上传处理过程中会回写的变量
MD5 string `json:"md5"` // 文件的MD5值 // 上传处理过程中会回写的变量
SHA1 string `json:"sha1"` // 文件的SHA1的值 // 上传过程中会回写的变量
Size int64 `json:"size"` // 文件的大小 // 上传处理过程中会回写的变量
}
// 上传文件处理
// 此方法会根据上传文件的后缀来判断是什么类型的文档,具体判定格式见下方lists
// PS:此方法仅作为上传/保存文件的目录,并不会生成缩略图/低质图等,缩略图等信息请再安排后续操作进行处理
func UploadFile(f *multipart.FileHeader, fc *FileConfig) error {
ext := strings.ToLower(path.Ext(f.Filename))
if ext != "" {
// 移除后缀前的.符号
ext = ext[1:]
}
// 后缀判断
err := checkExt(ext, fc)
if err != nil {
return err
}
// 保存文件位置判断
if err := checkConf(ext, fc); err != nil {
return err
}
// 文件大小限制
if fc.MaxSize > 0 {
if f.Size > fc.MaxSize {
return errors.New("文件大小超出限制")
}
}
fc.Size = f.Size
// 进行文件上传
src, err := f.Open()
if err != nil {
return err
}
defer src.Close()
out, err := os.Create(fc.SavePath + fc.SaveName)
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, src)
if err == nil {
fc.MD5 = xstring.MD5File(fc.SavePath + fc.SaveName)
fc.SHA1 = xstring.SHA1File(fc.SavePath + fc.SaveName)
}
return err
}
// 检测配置项能否允许上传,如检测大小、上传目录等
//
// ext 文件后缀
// fc 配置项信息
func checkConf(ext string, fc *FileConfig) error {
// 上传目录判断
if _, err := os.Stat(fc.SavePath); err != nil {
// 创建目录,因创建目录存在权限问题,所以此处使用mask方法进行创建并授权
if err = os.MkdirAll(fc.SavePath, os.ModePerm); err != nil {
return err
}
}
// 保存目录判断
if fc.SavePath[len(fc.SavePath)-1:] != "/" {
fc.SavePath += "/"
}
if fc.SaveName == "" {
// 如果savename传入的值为空,则生成一个30位长度的随机数,用来作为文件名进行存储
fc.SaveName = xstring.Random(30)
}
if strings.ToLower(path.Ext(fc.SaveName)) == "" {
fc.SaveName += "." + ext
}
if _, err := os.Stat(fc.SavePath + fc.SaveName); err == nil {
return errors.New("上传目录已存在")
}
return nil
}
// 判断是否允许某后缀文件上传
//
// ext 后缀文件名
// fc 上传配置项
func checkExt(ext string, fc *FileConfig) error {
// 图片
img := []string{"png", "jpg", "jpeg", "gif", "webp", "avif", "ico", "cur", "tga", "iff", "ani", "tiff", "bmp", "pcx", "jfif"}
// 文档
doc := []string{"txt", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "md", "mobi", "epub"}
// 音频
aud := []string{"mp3", "aac", "wav", "wma", "cda", "flac", "m4a", "mid", "mka", "mp2", "mpa", "mpc", "ape", "ofr", "ogg", "ra", "wv", "tta", "ac3", "dts"}
// 视频
vid := []string{"mpg", "mpeg", "avi", "rm", "rmvb", "mov", "wmv", "asf", "dat", "mp4", "asx", "wvx", "mpe", "mpa"}
// 配置项
con := []string{"ini", "yml", "env", "conf", "json"}
// 压缩包
zip := []string{"zip", "rar", "7z", "tar", "bz", "gz", "tgz", "tbz", "bz2"}
// 判断文件后缀是否允许上传
if ext != "" {
upd := false
if !upd && fc.UpImage {
upd = xnum.InArray(ext, img)
fc.IsImage = upd
}
if !upd && fc.UpDocument {
upd = xnum.InArray(ext, doc)
fc.IsDocument = upd
}
if !upd && fc.UpAudio {
upd = xnum.InArray(ext, aud)
fc.IsAudio = upd
}
if !upd && fc.UpVideo {
upd = xnum.InArray(ext, vid)
fc.IsVideo = upd
}
if !upd && fc.UpConfig {
upd = xnum.InArray(ext, con)
fc.IsConfig = upd
}
if !upd && fc.UpZip {
upd = xnum.InArray(ext, zip)
fc.IsZip = upd
}
if fc.UpOther {
// 是否允许其他格式文件上传
upd = true
fc.IsOther = true
}
if !upd {
return errors.New("文件格式不允许上传")
}
} else if !fc.UpNone {
return errors.New("禁止无后缀文件上传")
}
return nil
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/xiaoyutab/xgotool.git
git@gitee.com:xiaoyutab/xgotool.git
xiaoyutab
xgotool
xgotool
v0.3.34

搜索帮助