sys_file.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package system
  2. import (
  3. "path/filepath"
  4. "strconv"
  5. "strings"
  6. "github.com/gin-gonic/gin"
  7. "go_server/base/config"
  8. "go_server/global"
  9. "go_server/model/biz_modules/daytask"
  10. "go_server/model/common/response"
  11. "go_server/service/base"
  12. "go_server/utils"
  13. "gorm.io/gorm"
  14. )
  15. type FileService struct {
  16. base.SysCommonService
  17. }
  18. func (s *FileService) UploadFile(c *gin.Context) {
  19. _, header, err := c.Request.FormFile("file")
  20. if err != nil {
  21. response.Resp(c, "接收文件失败")
  22. return
  23. }
  24. path, file, err := config.EnvConf().File.UploadFile(header) // 文件上传后拿到文件路径
  25. if err != nil {
  26. response.Resp(c, err.Error())
  27. return
  28. }
  29. // 自动保存到素材库
  30. groupIdStr := c.PostForm("groupId")
  31. groupCode := c.PostForm("groupCode") // 分组代码,如 banner, task, notice 等
  32. autoSave := c.PostForm("autoSave") // 是否自动保存到素材库,默认true
  33. // 默认自动保存,除非明确设置为 "false" 或 "0"
  34. shouldSave := autoSave != "false" && autoSave != "0"
  35. if shouldSave {
  36. // 获取daytask数据库连接
  37. db, dbErr := global.BizDBByAlias("daytask")
  38. if dbErr == nil && db != nil {
  39. // 解析文件信息
  40. filename := header.Filename
  41. fileSize := header.Size
  42. mimeType := header.Header.Get("Content-Type")
  43. // 判断文件类型
  44. fileType := getFileType(mimeType, filename)
  45. // 获取groupId
  46. var groupId int64 = 0
  47. if groupIdStr != "" {
  48. groupId, _ = strconv.ParseInt(groupIdStr, 10, 64)
  49. } else if groupCode != "" {
  50. // 通过groupCode查找或创建分组
  51. groupId = getOrCreateGroupByCode(db, groupCode)
  52. }
  53. // 获取管理员ID
  54. adminId := c.GetInt64("userId")
  55. // 创建素材记录(不包含cover字段)
  56. material := daytask.DtMaterial{
  57. Name: filename,
  58. Path: file,
  59. Url: path,
  60. Type: fileType,
  61. MimeType: mimeType,
  62. Size: fileSize,
  63. Storage: "local",
  64. GroupId: groupId,
  65. AdminId: adminId,
  66. Status: 1,
  67. }
  68. // 保存到数据库,排除cover字段
  69. db.Omit("cover").Create(&material)
  70. }
  71. }
  72. response.Resp(c, map[string]interface{}{
  73. "path": path,
  74. "file": file,
  75. })
  76. }
  77. // getOrCreateGroupByCode 通过分组代码获取或创建分组
  78. func getOrCreateGroupByCode(db *gorm.DB, code string) int64 {
  79. // 分组代码与名称的映射
  80. codeNameMap := map[string]string{
  81. "banner": "Banner图片",
  82. "task": "任务素材",
  83. "task_icon": "任务图标",
  84. "category_icon": "分类图标",
  85. "notice": "公告素材",
  86. "help": "帮助中心",
  87. "avatar": "用户头像",
  88. "default": "默认分组",
  89. }
  90. // 查找已存在的分组
  91. var group daytask.DtMaterialGroup
  92. result := db.Where("code = ?", code).First(&group)
  93. if result.Error == nil {
  94. return group.Id
  95. }
  96. // 分组不存在,创建新分组
  97. groupName := codeNameMap[code]
  98. if groupName == "" {
  99. groupName = code // 如果没有映射,直接使用code作为名称
  100. }
  101. newGroup := daytask.DtMaterialGroup{
  102. Name: groupName,
  103. Code: code,
  104. Status: 1,
  105. }
  106. db.Create(&newGroup)
  107. return newGroup.Id
  108. }
  109. // getFileType 根据MIME类型和文件名判断文件类型
  110. func getFileType(mimeType, filename string) string {
  111. // 优先根据MIME类型判断
  112. if strings.HasPrefix(mimeType, "image/") {
  113. return "image"
  114. }
  115. if strings.HasPrefix(mimeType, "video/") {
  116. return "video"
  117. }
  118. if strings.HasPrefix(mimeType, "audio/") {
  119. return "audio"
  120. }
  121. // 根据文件扩展名判断
  122. ext := strings.ToLower(filepath.Ext(filename))
  123. switch ext {
  124. case ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", ".svg", ".ico":
  125. return "image"
  126. case ".mp4", ".avi", ".mov", ".wmv", ".flv", ".mkv", ".webm":
  127. return "video"
  128. case ".mp3", ".wav", ".ogg", ".flac", ".aac", ".m4a":
  129. return "audio"
  130. case ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".txt":
  131. return "document"
  132. default:
  133. return "other"
  134. }
  135. }
  136. func (s *FileService) DeleteFile(c *gin.Context) {
  137. filename, ok := c.GetQuery("filename")
  138. if !ok {
  139. response.Resp(c, "接收文件失败")
  140. return
  141. }
  142. err := config.EnvConf().File.DeleteFile(filename) // 文件上传后拿到文件路径
  143. if err != nil {
  144. response.Resp(c, err.Error())
  145. return
  146. }
  147. response.Resp(c)
  148. }
  149. func (s *FileService) OssAuth(c *gin.Context) {
  150. resp, err := config.StsAliEngin().AliSTS("fomo-sts")
  151. if err != nil {
  152. response.Resp(c, err.Error())
  153. return
  154. }
  155. savePath := utils.ToPath(config.EnvConf().StsOss.BasePath)
  156. response.Resp(c, map[string]any{
  157. "region": config.EnvConf().StsOss.StsRegion,
  158. "bucket": config.EnvConf().StsOss.BucketName,
  159. "bucketUrl": config.EnvConf().StsOss.BucketUrl,
  160. "credentials": resp.Body.Credentials,
  161. "filePath": savePath,
  162. })
  163. }