upload_local.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * @desc:本地上传
  3. * @company:云南省奇讯科技有限公司
  4. * @Author: yixiaohu
  5. * @Date: 2021/7/7 8:47
  6. */
  7. package adapter
  8. import (
  9. "gfast/app/common/model"
  10. "gfast/app/common/service"
  11. "github.com/gogf/gf/errors/gerror"
  12. "github.com/gogf/gf/net/ghttp"
  13. "github.com/gogf/gf/os/gtime"
  14. "github.com/gogf/gf/text/gregex"
  15. "github.com/gogf/gf/text/gstr"
  16. "github.com/gogf/gf/util/gconv"
  17. )
  18. type UploadLocalAdapter struct {
  19. UpPath string
  20. UploadPath string
  21. }
  22. // UpImg 上传图片
  23. func (up UploadLocalAdapter) UpImg(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
  24. return up.upByType(file, "img")
  25. }
  26. // UpFile 上传文件
  27. func (up UploadLocalAdapter) UpFile(file *ghttp.UploadFile) (fileInfo *FileInfo, err error) {
  28. return up.upByType(file, "file")
  29. }
  30. // UpImgs 批量上传图片
  31. func (up UploadLocalAdapter) UpImgs(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
  32. return up.upBathByType(files, "img")
  33. }
  34. // UpFiles 批量上传文件
  35. func (up UploadLocalAdapter) UpFiles(files []*ghttp.UploadFile) (fileInfos []*FileInfo, err error) {
  36. return up.upBathByType(files, "file")
  37. }
  38. //文件上传 img|file
  39. func (up UploadLocalAdapter) upByType(file *ghttp.UploadFile, fType string) (fileInfo *FileInfo, err error) {
  40. if file == nil {
  41. err = gerror.New("未上传任何文件")
  42. return
  43. }
  44. var (
  45. typeKey string
  46. sizeKey string
  47. )
  48. if fType == "img" {
  49. typeKey = "sys.uploadFile.imageType"
  50. sizeKey = "sys.uploadFile.imageSize"
  51. } else if fType == "file" {
  52. typeKey = "sys.uploadFile.fileType"
  53. sizeKey = "sys.uploadFile.fileSize"
  54. }
  55. //获取上传类型配置
  56. config, err := up.getUpConfig(typeKey)
  57. if err != nil {
  58. return
  59. }
  60. //检测文件类型
  61. rightType := up.checkFileType(file.Filename, config.ConfigValue)
  62. if !rightType {
  63. err = gerror.New("上传文件类型错误,只能包含后缀为:" + config.ConfigValue + "的文件。")
  64. return
  65. }
  66. //获取上传大小配置
  67. config, err = up.getUpConfig(sizeKey)
  68. if err != nil {
  69. return
  70. }
  71. rightSize, err := up.checkSize(config.ConfigValue, file.Size)
  72. if err != nil {
  73. return
  74. }
  75. if !rightSize {
  76. err = gerror.New("上传文件超过最大尺寸:" + config.ConfigValue)
  77. return
  78. }
  79. path := up.getUpPath()
  80. fileName, err := file.Save(path, true)
  81. if err != nil {
  82. return
  83. }
  84. fileInfo = &FileInfo{
  85. FileName: file.Filename,
  86. FileSize: file.Size,
  87. FileUrl: up.getUrl(path, fileName),
  88. FileType: file.Header.Get("Content-type"),
  89. }
  90. return
  91. }
  92. //批量上传 img|file
  93. func (up UploadLocalAdapter) upBathByType(files []*ghttp.UploadFile, fType string) (fileInfos []*FileInfo, err error) {
  94. if len(files) == 0 {
  95. err = gerror.New("未上传任何文件")
  96. return
  97. }
  98. var (
  99. typeKey string
  100. sizeKey string
  101. )
  102. if fType == "img" {
  103. typeKey = "sys.uploadFile.imageType"
  104. sizeKey = "sys.uploadFile.imageSize"
  105. } else if fType == "file" {
  106. typeKey = "sys.uploadFile.fileType"
  107. sizeKey = "sys.uploadFile.fileSize"
  108. }
  109. //获取上传类型配置
  110. configType, err := up.getUpConfig(typeKey)
  111. if err != nil {
  112. return
  113. }
  114. //获取上传大小配置
  115. configSize, err := up.getUpConfig(sizeKey)
  116. if err != nil {
  117. return
  118. }
  119. for _, file := range files {
  120. //检测文件类型
  121. rightType := up.checkFileType(file.Filename, configType.ConfigValue)
  122. if !rightType {
  123. err = gerror.New("上传文件类型错误,只能包含后缀为:" + configType.ConfigValue + "的文件。")
  124. return
  125. }
  126. var rightSize bool
  127. rightSize, err = up.checkSize(configSize.ConfigValue, file.Size)
  128. if err != nil {
  129. return
  130. }
  131. if !rightSize {
  132. err = gerror.New("上传文件超过最大尺寸:" + configSize.ConfigValue)
  133. return
  134. }
  135. }
  136. path := up.getUpPath()
  137. for _, file := range files {
  138. var fileName string
  139. fileName, err = file.Save(path, true)
  140. if err != nil {
  141. return
  142. }
  143. fileInfo := &FileInfo{
  144. FileName: file.Filename,
  145. FileSize: file.Size,
  146. FileUrl: up.getUrl(path, fileName),
  147. FileType: file.Header.Get("Content-type"),
  148. }
  149. fileInfos = append(fileInfos, fileInfo)
  150. }
  151. return
  152. }
  153. //检查文件大小是否合法
  154. func (up UploadLocalAdapter) checkSize(configSize string, fileSize int64) (bool, error) {
  155. match, err := gregex.MatchString(`^([0-9]+)(?i:([a-z]*))$`, configSize)
  156. if err != nil {
  157. return false, err
  158. }
  159. if len(match) == 0 {
  160. err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB)")
  161. return false, err
  162. }
  163. var cfSize int64
  164. switch gstr.ToUpper(match[2]) {
  165. case "MB", "M":
  166. cfSize = gconv.Int64(match[1]) * 1024 * 1024
  167. case "KB", "K":
  168. cfSize = gconv.Int64(match[1]) * 1024
  169. case "":
  170. cfSize = gconv.Int64(match[1])
  171. }
  172. if cfSize == 0 {
  173. err = gerror.New("上传文件大小未设置,请在后台配置,格式为(30M,30k,30MB),最大单位为MB")
  174. return false, err
  175. }
  176. return cfSize >= fileSize, nil
  177. }
  178. //获取上传配置
  179. func (up UploadLocalAdapter) getUpConfig(key string) (config *model.SysConfig, err error) {
  180. config, err = service.SysConfig.GetConfigByKey(key)
  181. if err != nil {
  182. return
  183. }
  184. if config == nil {
  185. err = gerror.New("上传文件类型未设置,请在后台配置")
  186. return
  187. }
  188. return
  189. }
  190. //判断上传文件类型是否合法
  191. func (up UploadLocalAdapter) checkFileType(fileName, typeString string) bool {
  192. suffix := gstr.SubStrRune(fileName, gstr.PosRRune(fileName, ".")+1, gstr.LenRune(fileName)-1)
  193. imageType := gstr.Split(typeString, ",")
  194. rightType := false
  195. for _, v := range imageType {
  196. if gstr.Equal(suffix, v) {
  197. rightType = true
  198. break
  199. }
  200. }
  201. return rightType
  202. }
  203. func (up UploadLocalAdapter) getUpPath() (upPath string) {
  204. upPath = up.UploadPath + gtime.Date() + "/"
  205. return
  206. }
  207. func (up UploadLocalAdapter) getUrl(path, fileName string) string {
  208. url := gstr.SubStr(path, gstr.Pos(path, up.UpPath)+1) + fileName
  209. return url
  210. }