asset.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. package plane_v2_api
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. plane "fwh-toolbox-server/repositories/api/plane_v2"
  6. )
  7. // CreateProjectAsset 创建项目资源(获取预签名 URL)
  8. func CreateProjectAsset(c *plane.PlaneClient, slug, projectID, fileName, mimeType string, size int64, entityType string) (*plane.AssetUploadResult, error) {
  9. url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/", slug, projectID)
  10. payload := map[string]interface{}{
  11. "name": fileName,
  12. "type": mimeType,
  13. "size": size,
  14. "entity_type": entityType,
  15. "entity_identifier": "",
  16. }
  17. resp, err := c.Post(url, payload)
  18. if err != nil {
  19. return nil, err
  20. }
  21. if !plane.IsSuccess(resp.StatusCode) {
  22. return nil, fmt.Errorf("CreateProjectAsset 失败: %s", resp.Status)
  23. }
  24. var result plane.AssetUploadResult
  25. if err := json.Unmarshal(resp.Body, &result); err != nil {
  26. return nil, fmt.Errorf("解析响应失败: %w", err)
  27. }
  28. return &result, nil
  29. }
  30. // ConfirmProjectAssetUpload 确认项目资源上传完成
  31. func ConfirmProjectAssetUpload(c *plane.PlaneClient, slug, projectID, assetID string) error {
  32. url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", slug, projectID, assetID)
  33. resp, err := c.Patch(url, map[string]interface{}{})
  34. if err != nil {
  35. return err
  36. }
  37. if resp.StatusCode != 204 && !plane.IsSuccess(resp.StatusCode) {
  38. return fmt.Errorf("ConfirmProjectAssetUpload 失败: %s", resp.Status)
  39. }
  40. return nil
  41. }
  42. // GetProjectAsset 获取项目资源
  43. func GetProjectAsset(c *plane.PlaneClient, slug, projectID, assetID string) ([]byte, error) {
  44. url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", slug, projectID, assetID)
  45. resp, err := c.Get(url)
  46. if err != nil {
  47. return nil, err
  48. }
  49. return resp.Body, nil
  50. }
  51. // GetProjectAssetURL 获取项目资源的预签名访问 URL
  52. func GetProjectAssetURL(c *plane.PlaneClient, slug, projectID, assetID string) (string, error) {
  53. url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", slug, projectID, assetID)
  54. return c.GetRedirectLocation(url)
  55. }
  56. // DeleteProjectAsset 删除项目资源
  57. func DeleteProjectAsset(c *plane.PlaneClient, slug, projectID, assetID string) error {
  58. url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", slug, projectID, assetID)
  59. resp, err := c.Delete(url)
  60. if err != nil {
  61. return err
  62. }
  63. if resp.StatusCode != 204 {
  64. return fmt.Errorf("DeleteProjectAsset 失败: %s", resp.Status)
  65. }
  66. return nil
  67. }
  68. // BindAssetsToEntity 批量绑定资源到实体
  69. func BindAssetsToEntity(c *plane.PlaneClient, slug, projectID, entityID string, assetIDs []string) error {
  70. url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/bulk/", slug, projectID, entityID)
  71. payload := map[string]interface{}{
  72. "asset_ids": assetIDs,
  73. }
  74. resp, err := c.Post(url, payload)
  75. if err != nil {
  76. return err
  77. }
  78. if resp.StatusCode != 204 && !plane.IsSuccess(resp.StatusCode) {
  79. return fmt.Errorf("BindAssetsToEntity 失败: %s", resp.Status)
  80. }
  81. return nil
  82. }
  83. // UploadToS3 上传文件到 S3(使用预签名 POST)
  84. func UploadToS3(c *plane.PlaneClient, uploadURL string, fields map[string]string, fileData []byte, fileName string) error {
  85. return c.PostS3(uploadURL, fields, fileData, fileName)
  86. }
  87. // UploadProjectAsset 完整上传项目资源流程:创建 → S3 上传 → 确认
  88. func UploadProjectAsset(c *plane.PlaneClient, slug, projectID, fileName, mimeType string, fileData []byte, entityType string) (*plane.AssetUploadResult, error) {
  89. // Step 1: 创建资源
  90. result, err := CreateProjectAsset(c, slug, projectID, fileName, mimeType, int64(len(fileData)), entityType)
  91. if err != nil {
  92. return nil, fmt.Errorf("创建资源失败: %w", err)
  93. }
  94. // Step 2: 上传到 S3
  95. if err := UploadToS3(c, result.UploadData.URL, result.UploadData.Fields, fileData, fileName); err != nil {
  96. return nil, fmt.Errorf("上传文件到S3失败: %w", err)
  97. }
  98. // Step 3: 确认上传完成
  99. if err := ConfirmProjectAssetUpload(c, slug, projectID, result.AssetID); err != nil {
  100. return nil, fmt.Errorf("确认上传失败: %w", err)
  101. }
  102. return result, nil
  103. }