file.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. package services
  2. import (
  3. "errors"
  4. "eta/eta_api/models"
  5. "eta/eta_api/utils"
  6. "fmt"
  7. "io"
  8. "mime/multipart"
  9. "os"
  10. "os/exec"
  11. "time"
  12. )
  13. // UploadToOssAndFileName 上传到oss并使用这个名称
  14. func UploadToOssAndFileName(fileMulti multipart.File, newFileName string) (resourceUrl string, err error) {
  15. dateDir := time.Now().Format("20060102")
  16. uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
  17. err = os.MkdirAll(uploadDir, utils.DIR_MOD)
  18. if err != nil {
  19. err = errors.New("存储目录创建失败,Err:" + err.Error())
  20. return
  21. }
  22. //本地地址
  23. fpath := uploadDir + "/" + newFileName
  24. err = saveToFile(fileMulti, fpath)
  25. if err != nil {
  26. err = errors.New("文件上传失败,Err:" + err.Error())
  27. return
  28. }
  29. //上传到阿里云 和 minio
  30. //if utils.ObjectStorageClient == "minio" {
  31. // resourceUrl, err = UploadImgToMinIo(newFileName, fpath)
  32. // if err != nil {
  33. // err = errors.New("文件上传失败,Err:" + err.Error())
  34. // return
  35. // }
  36. //} else {
  37. // resourceUrl, err = UploadAliyunV2(newFileName, fpath)
  38. // if err != nil {
  39. // err = errors.New("文件上传失败,Err:" + err.Error())
  40. // return
  41. // }
  42. //}
  43. ossClient := NewOssClient()
  44. if ossClient == nil {
  45. err = fmt.Errorf("初始化OSS服务失败")
  46. return
  47. }
  48. resourceUrl, err = ossClient.UploadFile(newFileName, fpath, "")
  49. if err != nil {
  50. err = fmt.Errorf("文件上传失败, Err: %s", err.Error())
  51. return
  52. }
  53. defer func() {
  54. os.Remove(fpath)
  55. }()
  56. item := new(models.Resource)
  57. item.ResourceUrl = resourceUrl
  58. item.ResourceType = 1
  59. item.CreateTime = time.Now()
  60. _, err = models.AddResource(item)
  61. if err != nil {
  62. err = errors.New("资源上传失败,Err:" + err.Error())
  63. return
  64. }
  65. return
  66. }
  67. // saveToFile 保存到本地文件
  68. func saveToFile(fileMulti multipart.File, tofile string) error {
  69. f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
  70. if err != nil {
  71. return err
  72. }
  73. defer f.Close()
  74. io.Copy(f, fileMulti)
  75. return nil
  76. }
  77. // GetResourceUrlBySvgImg
  78. // @Description: 通过svg图片生成图片资源地址(传到OSS后的地址)
  79. // @author: Roc
  80. // @datetime 2024-07-16 10:18:09
  81. // @param imgData string
  82. // @return resourceUrl string
  83. // @return err error
  84. // @return errMsg string
  85. func GetResourceUrlBySvgImg(imgData string) (resourceUrl string, err error, errMsg string) {
  86. errMsg = "图表保存失败"
  87. uploadDir := "static/images/"
  88. if !utils.FileIsExist(uploadDir) {
  89. err = os.MkdirAll(uploadDir, utils.DIR_MOD)
  90. if err != nil {
  91. err = errors.New("存储目录创建失败,Err:" + err.Error())
  92. return
  93. }
  94. }
  95. //var saveToOssPath string
  96. randStr := utils.GetRandStringNoSpecialChar(28)
  97. var fileName, outFileName string
  98. fileName = randStr + ".txt"
  99. fileName = uploadDir + fileName
  100. err = utils.SaveToFile(imgData, fileName)
  101. if err != nil {
  102. err = errors.New("图片保存失败,Err:" + err.Error())
  103. return
  104. }
  105. // 删除临时存储的svg文件
  106. defer func() {
  107. err = os.Remove(fileName)
  108. if err != nil {
  109. utils.FileLog.Info("删除临时存储的svg文件失败, err: " + err.Error())
  110. }
  111. }()
  112. outFileName = randStr + ".png"
  113. doneChannel := make(chan bool, 1)
  114. errorChannel := make(chan error, 1)
  115. cmd := exec.Command("highcharts-export-server", "--infile", fileName, "--constr", "Chart", "--scale", "2", "--workers", "10", "--workLimit", "3", "--outfile", outFileName)
  116. go func() {
  117. output, err := cmd.CombinedOutput()
  118. if err != nil {
  119. utils.FileLog.Info("execute command failed, output: , error: \n" + string(output) + err.Error())
  120. errorChannel <- err
  121. return
  122. }
  123. doneChannel <- true
  124. }()
  125. defer func() {
  126. _ = os.Remove(outFileName)
  127. if err != nil {
  128. utils.FileLog.Info("删除生产的图片文件失败, err: " + err.Error())
  129. }
  130. }()
  131. select {
  132. case <-time.After(30 * time.Second):
  133. utils.FileLog.Info("执行超过30秒 杀死超时进程")
  134. e := cmd.Process.Kill()
  135. if e != nil {
  136. fmt.Println("cmd kill err: ", e.Error())
  137. utils.FileLog.Info(fmt.Sprintf("cmd kill err: %s", e.Error()))
  138. errMsg = "图片生成失败"
  139. err = errors.New("图片生成失败, 执行超时" + e.Error())
  140. return
  141. }
  142. fmt.Println("timeout kill process")
  143. case <-doneChannel:
  144. fmt.Println("done")
  145. case e := <-errorChannel:
  146. errMsg = "文件上传失败"
  147. err = errors.New(fmt.Sprintf("execute command failure err: %s", e.Error()))
  148. fmt.Println("execute command failure err:" + e.Error())
  149. return
  150. }
  151. //上传到阿里云 和 minio
  152. ossClient := NewOssClient()
  153. if ossClient == nil {
  154. errMsg = "上传失败"
  155. err = errors.New("初始化OSS服务失败")
  156. return
  157. }
  158. resourceUrl, err = ossClient.UploadFile(outFileName, outFileName, "")
  159. if err != nil {
  160. errMsg = "文件上传失败"
  161. err = errors.New("文件上传失败,Err:" + err.Error())
  162. return
  163. }
  164. return
  165. }