batchDownloadControllers.go 7.2 KB

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