upload.go 5.5 KB

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