upload_local.go 6.0 KB

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