batchDownloadControllers.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. * Batch Download API List
  3. * /batchDownload/manage/list - GET
  4. * /batchDownload/manage/config - POST 创建新配置
  5. * /batchDownload/manage/description/{id} - POST 更新任务说明
  6. * /batchDownload/manage/config/{id} - DELETE 删除配置
  7. * /batchDownload/data/{id} - GET 获取指定ID的数据包下载地址
  8. * /batchDownload/manage/path - GET 获取指定ID的文件目录结构
  9. * /batchDownload/manage/fileTree - GET 获取指定文件的目录结构
  10. * /batchDownload/manage/fileDownload - GET 下载指定文件
  11. */
  12. package controllers
  13. import (
  14. "bufio"
  15. "fmt"
  16. "fwh-toolbox-server/domain"
  17. "fwh-toolbox-server/services"
  18. "fwh-toolbox-server/utils/mimetype"
  19. "path"
  20. "strconv"
  21. "strings"
  22. "github.com/gofiber/fiber/v2"
  23. "go.mongodb.org/mongo-driver/bson/primitive"
  24. "go.uber.org/zap"
  25. )
  26. // 获取批量数据下载管理表
  27. // /batchDownload/manage/list
  28. func GetBatchDownloadList(c *fiber.Ctx) error {
  29. pageInt, _ := strconv.Atoi(c.Query("pageNum", "1"))
  30. sizeInt, _ := strconv.Atoi(c.Query("pageSize", "20"))
  31. if pageInt <= 0 || sizeInt <= 0 {
  32. return Fail(c, "Invalid request para")
  33. }
  34. sn := c.Query("sn", "")
  35. progress := c.Query("progress", "")
  36. var p_sn *string = nil
  37. if sn != "" {
  38. p_sn = &sn
  39. }
  40. var p_progress *string = nil
  41. if progress != "" {
  42. p_progress = &progress
  43. }
  44. listPage, err := services.GetBatchDownloadManageList(uint(pageInt), uint(sizeInt), p_sn, p_progress)
  45. if err != nil {
  46. zap.L().Warn("Database read failed. (MongoDb)", zap.String("err", err.Error()))
  47. return Error(c, "Database read failed. (MongoDb)")
  48. }
  49. return Success(c, listPage)
  50. }
  51. // 创建一个批量数据下载管任务
  52. // /batchDownload/manage/config
  53. func CreateBatchDownload(c *fiber.Ctx) error {
  54. var body domain.BatchDownloadConfigWrite
  55. if err := c.BodyParser(&body); err != nil {
  56. zap.L().Warn("Invalid request body", zap.String("err", err.Error()))
  57. return Fail(c, "Invalid request body")
  58. }
  59. if err := services.InsertBatchDownloadConfig(body); err != nil {
  60. zap.L().Warn("Database write failed. (MongoDb)", zap.String("err", err.Error()))
  61. return Error(c, "Database write failed. (MongoDb)")
  62. }
  63. return Success(c, body)
  64. }
  65. // 更新一个批量数据下载说明
  66. // /batchDownload/manage/description/:id
  67. func UpdateBatchDownloadDescription(c *fiber.Ctx) error {
  68. id := c.Params("id")
  69. var body string
  70. if err := c.BodyParser(&body); err != nil {
  71. zap.L().Warn("Invalid request body", zap.String("err", err.Error()))
  72. return Fail(c, "Invalid request body")
  73. }
  74. objID, err := primitive.ObjectIDFromHex(id)
  75. if err != nil {
  76. zap.L().Warn("Invalid request para :id", zap.String("err", err.Error()))
  77. return Fail(c, "Invalid request para :id")
  78. }
  79. if err := services.UpdateBatchDownloadDescription(objID, body); err != nil {
  80. zap.L().Warn("Database write failed. (MongoDb)", zap.String("err", err.Error()))
  81. return Error(c, "Database write failed. (MongoDb)")
  82. }
  83. return Success(c, body)
  84. }
  85. // 删除一个批量数据下载数据
  86. // /batchDownload/manage/config/:id
  87. func DeleteBatchDownload(c *fiber.Ctx) error {
  88. id := c.Params("id")
  89. objID, err := primitive.ObjectIDFromHex(id)
  90. if err != nil {
  91. zap.L().Warn("Invalid request para :id", zap.String("err", err.Error()))
  92. return Fail(c, "Invalid request para :id")
  93. }
  94. err = services.DeleteBatchDownloadConfig(objID)
  95. if err != nil {
  96. zap.L().Warn("Database delete failed. (MongoDb)", zap.String("err", err.Error()))
  97. return Error(c, "Database delete failed. (MongoDb)")
  98. }
  99. return NoContent(c)
  100. }
  101. // 获取指定ID的批量数据下载数据包地址
  102. // /batchDownload/data/:id
  103. func GetBatchDownloadData(c *fiber.Ctx) error {
  104. id := c.Params("id")
  105. objID, err := primitive.ObjectIDFromHex(id)
  106. if err != nil {
  107. zap.L().Warn("Invalid request para :id", zap.String("err", err.Error()))
  108. return Fail(c, "Invalid request para :id")
  109. }
  110. c.Set("Content-Type", "application/zip")
  111. c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"BatchDownload_%s.zip\"", id))
  112. // Fiber 原生 Context 的 BodyWriter,可直接写数据到 HTTP 输出
  113. // writer := c.Context().Response.BodyWriter()
  114. // 使用 SetBodyStreamWriter 流式写入
  115. c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
  116. err = services.GetBatchDownloadData(objID, w)
  117. if err != nil {
  118. zap.L().Warn("Database read failed. (MongoDb)", zap.String("err", err.Error()))
  119. return
  120. }
  121. w.Flush()
  122. fmt.Println("SetBodyStreamWriter complete.")
  123. })
  124. return nil
  125. }
  126. // 获取指定ID的文件目录结构
  127. // /batchDownload/manage/path
  128. func GetBatchDownloadPath(c *fiber.Ctx) error {
  129. id := c.Query("id", "")
  130. objID, err := primitive.ObjectIDFromHex(id)
  131. if err != nil {
  132. zap.L().Warn("Invalid request para :id", zap.String("err", err.Error()))
  133. return Fail(c, "Invalid request para :id")
  134. }
  135. pathInfo, err := services.GetBatchDownloadPath(objID)
  136. if err != nil {
  137. zap.L().Warn("Path query failed.", zap.String("err", err.Error()))
  138. return Error(c, "Path query failed.")
  139. }
  140. return Success(c, pathInfo)
  141. }
  142. // 获取指定文件的目录结构
  143. // /batchDownload/manage/fileTree
  144. func GetBatchDownloadFileTree(c *fiber.Ctx) error {
  145. filePath := c.Query("file", "")
  146. pathInfo, err := services.GetBatchDownloadFileTree(filePath)
  147. if err != nil {
  148. zap.L().Warn("File tree query failed.", zap.String("err", err.Error()))
  149. return Error(c, "File tree query failed.")
  150. }
  151. return Success(c, pathInfo)
  152. }
  153. // 下载指定文件
  154. // /batchDownload/manage/fileDownload
  155. func GetBatchDownloadFileDownload(c *fiber.Ctx) error {
  156. filePath := c.Query("file", "")
  157. innerPath := c.Query("inner", "")
  158. var fileName string
  159. if innerPath == "" {
  160. fileName = path.Base(filePath)
  161. } else {
  162. if !strings.HasSuffix(filePath, ".tar.gz") {
  163. return Error(c, "File path suffix not is \".tar.gz\".")
  164. }
  165. fileName = path.Base(innerPath)
  166. }
  167. if fileName == "." {
  168. return Error(c, "File path is empty.")
  169. } else if fileName == "/" {
  170. return Error(c, "File path consists entirely of slashes.")
  171. }
  172. c.Set("Content-Type", mimetype.GetContentType(fileName))
  173. c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", fileName))
  174. // Fiber 原生 Context 的 BodyWriter,可直接写数据到 HTTP 输出
  175. // writer := c.Context().Response.BodyWriter()
  176. // 使用 SetBodyStreamWriter 流式写入
  177. c.Context().SetBodyStreamWriter(func(w *bufio.Writer) {
  178. err := services.GetBatchDownloadFileDownload(filePath, innerPath, w)
  179. if err != nil {
  180. zap.L().Warn("File read failed.", zap.String("err", err.Error()))
  181. return
  182. }
  183. w.Flush()
  184. fmt.Println("SetBodyStreamWriter complete.")
  185. })
  186. return nil
  187. }