plane_issue.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package plane_v2
  2. import (
  3. "fmt"
  4. "go.uber.org/zap"
  5. )
  6. // ==================== Issue (Work Item) API ====================
  7. // ListIssues 列出工作项
  8. func ListIssues(slug, projectID string) ([]byte, error) {
  9. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", slug, projectID)
  10. resp, err := planeWebGet(url)
  11. if err != nil {
  12. zap.L().Error("[PlaneWeb] ListIssues 请求失败", zap.Error(err))
  13. return nil, err
  14. }
  15. if !isWebSuccess(resp.StatusCode) {
  16. zap.L().Error("[PlaneWeb] ListIssues 返回错误", zap.String("status", resp.Status))
  17. return nil, fmt.Errorf("ListIssues 失败: %s", resp.Status)
  18. }
  19. return resp.Body, nil
  20. }
  21. // CreateIssue 创建工作项
  22. func CreateIssue(slug, projectID string, data map[string]interface{}) ([]byte, error) {
  23. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", slug, projectID)
  24. resp, err := planeWebPost(url, data)
  25. if err != nil {
  26. zap.L().Error("[PlaneWeb] CreateIssue 请求失败", zap.Error(err))
  27. return nil, err
  28. }
  29. if resp.StatusCode != 201 {
  30. zap.L().Error("[PlaneWeb] CreateIssue 返回错误",
  31. zap.String("status", resp.Status),
  32. zap.String("body", string(resp.Body)),
  33. )
  34. return nil, fmt.Errorf("CreateIssue 失败: %s", resp.Status)
  35. }
  36. return resp.Body, nil
  37. }
  38. // GetIssue 获取工作项详情
  39. func GetIssue(slug, projectID, issueID string) ([]byte, error) {
  40. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", slug, projectID, issueID)
  41. resp, err := planeWebGet(url)
  42. if err != nil {
  43. zap.L().Error("[PlaneWeb] GetIssue 请求失败", zap.Error(err))
  44. return nil, err
  45. }
  46. if !isWebSuccess(resp.StatusCode) {
  47. zap.L().Error("[PlaneWeb] GetIssue 返回错误", zap.String("status", resp.Status))
  48. return nil, fmt.Errorf("GetIssue 失败: %s", resp.Status)
  49. }
  50. return resp.Body, nil
  51. }
  52. // UpdateIssue 更新工作项
  53. func UpdateIssue(slug, projectID, issueID string, data map[string]interface{}) ([]byte, error) {
  54. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", slug, projectID, issueID)
  55. resp, err := planeWebPatch(url, data)
  56. if err != nil {
  57. zap.L().Error("[PlaneWeb] UpdateIssue 请求失败", zap.Error(err))
  58. return nil, err
  59. }
  60. if !isWebSuccess(resp.StatusCode) {
  61. zap.L().Error("[PlaneWeb] UpdateIssue 返回错误",
  62. zap.String("status", resp.Status),
  63. zap.String("body", string(resp.Body)),
  64. )
  65. return nil, fmt.Errorf("UpdateIssue 失败: %s", resp.Status)
  66. }
  67. return resp.Body, nil
  68. }
  69. // DeleteIssue 删除工作项
  70. func DeleteIssue(slug, projectID, issueID string) error {
  71. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", slug, projectID, issueID)
  72. resp, err := planeWebDelete(url)
  73. if err != nil {
  74. zap.L().Error("[PlaneWeb] DeleteIssue 请求失败", zap.Error(err))
  75. return err
  76. }
  77. if resp.StatusCode != 204 {
  78. zap.L().Error("[PlaneWeb] DeleteIssue 返回错误", zap.String("status", resp.Status))
  79. return fmt.Errorf("DeleteIssue 失败: %s", resp.Status)
  80. }
  81. return nil
  82. }
  83. // GetSubIssues 获取子工作项
  84. func GetSubIssues(slug, projectID, issueID string) ([]byte, error) {
  85. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/sub-issues/", slug, projectID, issueID)
  86. resp, err := planeWebGet(url)
  87. if err != nil {
  88. zap.L().Error("[PlaneWeb] GetSubIssues 请求失败", zap.Error(err))
  89. return nil, err
  90. }
  91. if !isWebSuccess(resp.StatusCode) {
  92. zap.L().Error("[PlaneWeb] GetSubIssues 返回错误", zap.String("status", resp.Status))
  93. return nil, fmt.Errorf("GetSubIssues 失败: %s", resp.Status)
  94. }
  95. return resp.Body, nil
  96. }
  97. // ArchiveIssue 归档工作项
  98. func ArchiveIssue(slug, projectID, issueID string) error {
  99. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", slug, projectID, issueID)
  100. resp, err := planeWebPost(url, map[string]interface{}{})
  101. if err != nil {
  102. zap.L().Error("[PlaneWeb] ArchiveIssue 请求失败", zap.Error(err))
  103. return err
  104. }
  105. if !isWebSuccess(resp.StatusCode) {
  106. zap.L().Error("[PlaneWeb] ArchiveIssue 返回错误", zap.String("status", resp.Status))
  107. return fmt.Errorf("ArchiveIssue 失败: %s", resp.Status)
  108. }
  109. return nil
  110. }
  111. // UnarchiveIssue 取消归档工作项
  112. func UnarchiveIssue(slug, projectID, issueID string) error {
  113. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", slug, projectID, issueID)
  114. resp, err := planeWebDelete(url)
  115. if err != nil {
  116. zap.L().Error("[PlaneWeb] UnarchiveIssue 请求失败", zap.Error(err))
  117. return err
  118. }
  119. if !isWebSuccess(resp.StatusCode) {
  120. zap.L().Error("[PlaneWeb] UnarchiveIssue 返回错误", zap.String("status", resp.Status))
  121. return fmt.Errorf("UnarchiveIssue 失败: %s", resp.Status)
  122. }
  123. return nil
  124. }
  125. // GetIssueActivity 获取工作项活动历史
  126. func GetIssueActivity(slug, projectID, issueID string) ([]byte, error) {
  127. url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/history/", slug, projectID, issueID)
  128. resp, err := planeWebGet(url)
  129. if err != nil {
  130. zap.L().Error("[PlaneWeb] GetIssueActivity 请求失败", zap.Error(err))
  131. return nil, err
  132. }
  133. if !isWebSuccess(resp.StatusCode) {
  134. zap.L().Error("[PlaneWeb] GetIssueActivity 返回错误", zap.String("status", resp.Status))
  135. return nil, fmt.Errorf("GetIssueActivity 失败: %s", resp.Status)
  136. }
  137. return resp.Body, nil
  138. }
  139. // ListCurrentIssues 列出当前项目下的工作项
  140. func ListCurrentIssues() ([]byte, error) {
  141. return ListIssues(webWorkspaceSlug, webProjectId)
  142. }
  143. // CreateCurrentIssue 在当前项目下创建工作项
  144. func CreateCurrentIssue(data map[string]interface{}) ([]byte, error) {
  145. return CreateIssue(webWorkspaceSlug, webProjectId, data)
  146. }