|
|
@@ -5,440 +5,462 @@ import (
|
|
|
"fmt"
|
|
|
)
|
|
|
|
|
|
-// PlaneService 便捷封装(绑定固定的 workspace/project,共享全局 PlaneClient)
|
|
|
+// PlaneService 通用 Plane API 封装(无绑定配置,workspace/project 通过参数传入)
|
|
|
type PlaneService struct {
|
|
|
- Client *PlaneClient
|
|
|
- WorkspaceSlug string
|
|
|
- ProjectId string
|
|
|
- LabelBugId string
|
|
|
- LabelFeatureId string
|
|
|
- LabelFeedbackId string
|
|
|
+ Client *PlaneClient
|
|
|
}
|
|
|
|
|
|
-// NewPlaneService 创建 PlaneService(须先调用 InitPlaneClient)
|
|
|
-func NewPlaneService(workspaceSlug, projectId, labelBugId, labelFeatureId, labelFeedbackId string) *PlaneService {
|
|
|
+// NewPlaneService 创建通用 PlaneService(须先调用 InitPlaneClient)
|
|
|
+func NewPlaneService() *PlaneService {
|
|
|
if globalClient == nil {
|
|
|
panic("[PlaneService] PlaneClient 未初始化,请先调用 InitPlaneClient")
|
|
|
}
|
|
|
-
|
|
|
- return &PlaneService{
|
|
|
- Client: globalClient,
|
|
|
- WorkspaceSlug: workspaceSlug,
|
|
|
- ProjectId: projectId,
|
|
|
- LabelBugId: labelBugId,
|
|
|
- LabelFeatureId: labelFeatureId,
|
|
|
- LabelFeedbackId: labelFeedbackId,
|
|
|
- }
|
|
|
+ return &PlaneService{Client: globalClient}
|
|
|
}
|
|
|
|
|
|
-// ============ Intake 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) CreateIntakeIssue(issue IntakeIssueRequest) (*IntakeIssueResponse, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- payload := map[string]any{"source": "IN_APP", "issue": issue}
|
|
|
+// ============ Workspace 方法 ============
|
|
|
|
|
|
- resp, err := s.Client.Post(url, payload)
|
|
|
+func (s *PlaneService) ListWorkspaces() ([]byte, error) {
|
|
|
+ resp, err := s.Client.Get("/api/workspaces/")
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateIntakeIssue 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- var result IntakeIssueResponse
|
|
|
- if err := json.Unmarshal(resp.Body, &result); err != nil {
|
|
|
- return nil, err
|
|
|
+ return nil, fmt.Errorf("ListWorkspaces 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return &result, nil
|
|
|
+ return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ListIntakeIssues(status string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- if status != "" {
|
|
|
- url += "?status=" + status
|
|
|
- }
|
|
|
+func (s *PlaneService) GetWorkspace(workspaceSlug string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/", workspaceSlug)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListIntakeIssues 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("GetWorkspace 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetIntakeIssue(issueID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/%s/?expand=issue_inbox", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
+func (s *PlaneService) CreateWorkspace(name, slug string) ([]byte, error) {
|
|
|
+ payload := map[string]interface{}{"name": name, "slug": slug}
|
|
|
+ resp, err := s.Client.Post("/api/workspaces/", payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetIntakeIssue 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("CreateWorkspace 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-// ============ Asset 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) UploadProjectAsset(fileName, mimeType string, fileData []byte, entityType string) (*AssetUploadResult, error) {
|
|
|
- // Step 1: 创建资源
|
|
|
- createURL := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- createPayload := map[string]any{
|
|
|
- "name": fileName, "type": mimeType, "size": len(fileData),
|
|
|
- "entity_type": entityType, "entity_identifier": "",
|
|
|
- }
|
|
|
- resp, err := s.Client.Post(createURL, createPayload)
|
|
|
+func (s *PlaneService) UpdateWorkspace(workspaceSlug string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/", workspaceSlug)
|
|
|
+ resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateProjectAsset 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- var result AssetUploadResult
|
|
|
- if err := json.Unmarshal(resp.Body, &result); err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
-
|
|
|
- // Step 2: 上传到 S3
|
|
|
- if err := s.Client.PostS3(result.UploadData.URL, result.UploadData.Fields, fileData, fileName); err != nil {
|
|
|
- return nil, err
|
|
|
+ return nil, fmt.Errorf("UpdateWorkspace 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
-
|
|
|
- // Step 3: 确认
|
|
|
- confirmURL := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", s.WorkspaceSlug, s.ProjectId, result.AssetID)
|
|
|
- s.Client.Patch(confirmURL, map[string]any{})
|
|
|
-
|
|
|
- return &result, nil
|
|
|
-}
|
|
|
-
|
|
|
-func (s *PlaneService) GetProjectAssetURL(assetID string) (string, error) {
|
|
|
- url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", s.WorkspaceSlug, s.ProjectId, assetID)
|
|
|
- return s.Client.GetRedirectLocation(url)
|
|
|
+ return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteProjectAsset(assetID string) error {
|
|
|
- url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", s.WorkspaceSlug, s.ProjectId, assetID)
|
|
|
+func (s *PlaneService) DeleteWorkspace(workspaceSlug string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/", workspaceSlug)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteProjectAsset 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (s *PlaneService) BindAssetsToEntity(entityID string, assetIDs []string) error {
|
|
|
- url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/bulk/", s.WorkspaceSlug, s.ProjectId, entityID)
|
|
|
- resp, err := s.Client.Post(url, map[string]any{"asset_ids": assetIDs})
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if resp.StatusCode != 204 && !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("BindAssetsToEntity 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("DeleteWorkspace 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Page 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) ListPages() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListPages 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- return resp.Body, nil
|
|
|
-}
|
|
|
+// ============ Project 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) GetPage(pageID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/", s.WorkspaceSlug, s.ProjectId, pageID)
|
|
|
+func (s *PlaneService) ListProjects(workspaceSlug string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/", workspaceSlug)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetPage 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListProjects 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetPageDescription(pageID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/description/", s.WorkspaceSlug, s.ProjectId, pageID)
|
|
|
+func (s *PlaneService) GetProject(workspaceSlug, projectID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/", workspaceSlug, projectID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetPageDescription 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("GetProject 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-// ============ Workspace 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) ListWorkspaces() ([]byte, error) {
|
|
|
- resp, err := s.Client.Get("/api/workspaces/")
|
|
|
+func (s *PlaneService) CreateProject(workspaceSlug string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/", workspaceSlug)
|
|
|
+ resp, err := s.Client.Post(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListWorkspaces 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("CreateProject 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetWorkspace() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/", s.WorkspaceSlug)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
+func (s *PlaneService) UpdateProject(workspaceSlug, projectID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/", workspaceSlug, projectID)
|
|
|
+ resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetWorkspace 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("UpdateProject 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateWorkspace(name, slug string) ([]byte, error) {
|
|
|
- payload := map[string]interface{}{"name": name, "slug": slug}
|
|
|
- resp, err := s.Client.Post("/api/workspaces/", payload)
|
|
|
+func (s *PlaneService) DeleteProject(workspaceSlug, projectID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/", workspaceSlug, projectID)
|
|
|
+ resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return err
|
|
|
}
|
|
|
- if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateWorkspace 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ if resp.StatusCode != 204 {
|
|
|
+ return fmt.Errorf("DeleteProject 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return resp.Body, nil
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateWorkspace(data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/", s.WorkspaceSlug)
|
|
|
- resp, err := s.Client.Patch(url, data)
|
|
|
+func (s *PlaneService) ArchiveProject(workspaceSlug, projectID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/archive/", workspaceSlug, projectID)
|
|
|
+ resp, err := s.Client.Post(url, nil)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateWorkspace 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return fmt.Errorf("ArchiveProject 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return resp.Body, nil
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteWorkspace() error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/", s.WorkspaceSlug)
|
|
|
+func (s *PlaneService) UnarchiveProject(workspaceSlug, projectID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/archive/", workspaceSlug, projectID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteWorkspace 失败: %s", resp.Status)
|
|
|
+ if !IsSuccess(resp.StatusCode) {
|
|
|
+ return fmt.Errorf("UnarchiveProject 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Project 便捷方法 ============
|
|
|
+// ============ Issue 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) ListProjects() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/", s.WorkspaceSlug)
|
|
|
+func (s *PlaneService) ListIssues(workspaceSlug, projectId string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListProjects 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListIssues 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetProject(projectID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/", s.WorkspaceSlug, projectID)
|
|
|
+func (s *PlaneService) GetIssue(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetProject 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("GetIssue 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateProject(data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/", s.WorkspaceSlug)
|
|
|
+func (s *PlaneService) CreateIssue(workspaceSlug, projectId string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Post(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateProject 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("CreateIssue 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateProject(projectID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/", s.WorkspaceSlug, projectID)
|
|
|
+func (s *PlaneService) UpdateIssue(workspaceSlug, projectId, issueID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateProject 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("UpdateIssue 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteProject(projectID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/", s.WorkspaceSlug, projectID)
|
|
|
+func (s *PlaneService) DeleteIssue(workspaceSlug, projectId, issueID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteProject 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("DeleteIssue 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ArchiveProject(projectID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/archive/", s.WorkspaceSlug, projectID)
|
|
|
+func (s *PlaneService) GetSubIssues(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/sub-issues/", workspaceSlug, projectId, issueID)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if !IsSuccess(resp.StatusCode) {
|
|
|
+ return nil, fmt.Errorf("GetSubIssues 失败: %s", resp.Status)
|
|
|
+ }
|
|
|
+ return resp.Body, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s *PlaneService) ArchiveIssue(workspaceSlug, projectId, issueID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Post(url, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("ArchiveProject 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("ArchiveIssue 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UnarchiveProject(projectID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/archive/", s.WorkspaceSlug, projectID)
|
|
|
+func (s *PlaneService) UnarchiveIssue(workspaceSlug, projectId, issueID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("UnarchiveProject 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("UnarchiveIssue 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Issue 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) ListIssues() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) GetIssueActivity(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/history/?activity_type=issue-property", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListIssues 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("GetIssueActivity 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetIssue(issueID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
+// ============ Intake 方法 ============
|
|
|
+
|
|
|
+func (s *PlaneService) CreateIntakeIssue(workspaceSlug, projectId string, issue IntakeIssueRequest) (*IntakeIssueResponse, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/", workspaceSlug, projectId)
|
|
|
+ payload := map[string]any{"source": "IN_APP", "issue": issue}
|
|
|
+
|
|
|
+ resp, err := s.Client.Post(url, payload)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if !IsSuccess(resp.StatusCode) {
|
|
|
+ return nil, fmt.Errorf("CreateIntakeIssue 失败: %s", resp.Status)
|
|
|
+ }
|
|
|
+ var result IntakeIssueResponse
|
|
|
+ if err := json.Unmarshal(resp.Body, &result); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return &result, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s *PlaneService) ListIntakeIssues(workspaceSlug, projectId, status string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/", workspaceSlug, projectId)
|
|
|
+ if status != "" {
|
|
|
+ url += "?status=" + status
|
|
|
+ }
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetIssue 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListIntakeIssues 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateIssue(data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- resp, err := s.Client.Post(url, data)
|
|
|
+func (s *PlaneService) GetIntakeIssue(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/%s/?expand=issue_inbox", workspaceSlug, projectId, issueID)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateIssue 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("GetIntakeIssue 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateIssue(issueID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
+func (s *PlaneService) UpdateIntakeIssue(workspaceSlug, projectId, issueID string, data map[string]any) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/%s/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateIssue 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("UpdateIntakeIssue 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteIssue(issueID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
+func (s *PlaneService) AcceptIntakeIssue(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ return s.UpdateIntakeIssue(workspaceSlug, projectId, issueID, map[string]any{"status": 1})
|
|
|
+}
|
|
|
+
|
|
|
+func (s *PlaneService) RejectIntakeIssue(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ return s.UpdateIntakeIssue(workspaceSlug, projectId, issueID, map[string]any{"status": -1})
|
|
|
+}
|
|
|
+
|
|
|
+func (s *PlaneService) DeleteIntakeIssue(workspaceSlug, projectId, issueID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/%s/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteIssue 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("DeleteIntakeIssue 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetSubIssues(issueID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/sub-issues/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
+// ============ Asset 方法 ============
|
|
|
+
|
|
|
+func (s *PlaneService) UploadProjectAsset(workspaceSlug, projectId, fileName, mimeType string, fileData []byte, entityType string) (*AssetUploadResult, error) {
|
|
|
+ // Step 1: 创建资源
|
|
|
+ createURL := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/", workspaceSlug, projectId)
|
|
|
+ createPayload := map[string]any{
|
|
|
+ "name": fileName, "type": mimeType, "size": len(fileData),
|
|
|
+ "entity_type": entityType, "entity_identifier": "",
|
|
|
+ }
|
|
|
+ resp, err := s.Client.Post(createURL, createPayload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetSubIssues 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("CreateProjectAsset 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return resp.Body, nil
|
|
|
+ var result AssetUploadResult
|
|
|
+ if err := json.Unmarshal(resp.Body, &result); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ // Step 2: 上传到 S3
|
|
|
+ if err := s.Client.PostS3(result.UploadData.URL, result.UploadData.Fields, fileData, fileName); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ // Step 3: 确认
|
|
|
+ confirmURL := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", workspaceSlug, projectId, result.AssetID)
|
|
|
+ s.Client.Patch(confirmURL, map[string]any{})
|
|
|
+
|
|
|
+ return &result, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ArchiveIssue(issueID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Post(url, nil)
|
|
|
+func (s *PlaneService) CreateProjectAsset(workspaceSlug, projectId, fileName, mimeType string, size int64, entityType string) (*AssetUploadResult, error) {
|
|
|
+ url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/", workspaceSlug, projectId)
|
|
|
+ payload := map[string]interface{}{
|
|
|
+ "name": fileName, "type": mimeType, "size": size,
|
|
|
+ "entity_type": entityType, "entity_identifier": "",
|
|
|
+ }
|
|
|
+ resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("ArchiveIssue 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("CreateProjectAsset 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return nil
|
|
|
+ var result AssetUploadResult
|
|
|
+ if err := json.Unmarshal(resp.Body, &result); err != nil {
|
|
|
+ return nil, fmt.Errorf("解析响应失败: %w", err)
|
|
|
+ }
|
|
|
+ return &result, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UnarchiveIssue(issueID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Delete(url)
|
|
|
+func (s *PlaneService) ConfirmProjectAssetUpload(workspaceSlug, projectId, assetID string) error {
|
|
|
+ url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", workspaceSlug, projectId, assetID)
|
|
|
+ resp, err := s.Client.Patch(url, map[string]interface{}{})
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- if !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("UnarchiveIssue 失败: %s", resp.Status)
|
|
|
+ if resp.StatusCode != 204 && !IsSuccess(resp.StatusCode) {
|
|
|
+ return fmt.Errorf("ConfirmProjectAssetUpload 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetIssueActivity(issueID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/history/?activity_type=issue-property", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
+func (s *PlaneService) GetProjectAssetURL(workspaceSlug, projectId, assetID string) (string, error) {
|
|
|
+ url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", workspaceSlug, projectId, assetID)
|
|
|
+ return s.Client.GetRedirectLocation(url)
|
|
|
+}
|
|
|
+
|
|
|
+func (s *PlaneService) GetProjectAsset(workspaceSlug, projectId, assetID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", workspaceSlug, projectId, assetID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
- if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetIssueActivity 失败: %s", resp.Status)
|
|
|
- }
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-// ============ Cycle 便捷方法 ============
|
|
|
+func (s *PlaneService) DeleteProjectAsset(workspaceSlug, projectId, assetID string) error {
|
|
|
+ url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", workspaceSlug, projectId, assetID)
|
|
|
+ resp, err := s.Client.Delete(url)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if resp.StatusCode != 204 {
|
|
|
+ return fmt.Errorf("DeleteProjectAsset 失败: %s", resp.Status)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s *PlaneService) BindAssetsToEntity(workspaceSlug, projectId, entityID string, assetIDs []string) error {
|
|
|
+ url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/bulk/", workspaceSlug, projectId, entityID)
|
|
|
+ resp, err := s.Client.Post(url, map[string]any{"asset_ids": assetIDs})
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ if resp.StatusCode != 204 && !IsSuccess(resp.StatusCode) {
|
|
|
+ return fmt.Errorf("BindAssetsToEntity 失败: %s", resp.Status)
|
|
|
+ }
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+// ============ Cycle 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) ListCycles() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) ListCycles(workspaceSlug, projectId string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -449,8 +471,8 @@ func (s *PlaneService) ListCycles() ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetCycle(cycleID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", s.WorkspaceSlug, s.ProjectId, cycleID)
|
|
|
+func (s *PlaneService) GetCycle(workspaceSlug, projectId, cycleID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", workspaceSlug, projectId, cycleID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -461,8 +483,8 @@ func (s *PlaneService) GetCycle(cycleID string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateCycle(data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) CreateCycle(workspaceSlug, projectId string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Post(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -473,8 +495,8 @@ func (s *PlaneService) CreateCycle(data map[string]interface{}) ([]byte, error)
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateCycle(cycleID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", s.WorkspaceSlug, s.ProjectId, cycleID)
|
|
|
+func (s *PlaneService) UpdateCycle(workspaceSlug, projectId, cycleID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", workspaceSlug, projectId, cycleID)
|
|
|
resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -485,8 +507,8 @@ func (s *PlaneService) UpdateCycle(cycleID string, data map[string]interface{})
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteCycle(cycleID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", s.WorkspaceSlug, s.ProjectId, cycleID)
|
|
|
+func (s *PlaneService) DeleteCycle(workspaceSlug, projectId, cycleID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", workspaceSlug, projectId, cycleID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -497,8 +519,8 @@ func (s *PlaneService) DeleteCycle(cycleID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ListCycleIssues(cycleID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/", s.WorkspaceSlug, s.ProjectId, cycleID)
|
|
|
+func (s *PlaneService) ListCycleIssues(workspaceSlug, projectId, cycleID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/", workspaceSlug, projectId, cycleID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -509,8 +531,8 @@ func (s *PlaneService) ListCycleIssues(cycleID string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) AddIssuesToCycle(cycleID string, issueIDs []string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/", s.WorkspaceSlug, s.ProjectId, cycleID)
|
|
|
+func (s *PlaneService) AddIssuesToCycle(workspaceSlug, projectId, cycleID string, issueIDs []string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/", workspaceSlug, projectId, cycleID)
|
|
|
payload := map[string]interface{}{"issues": issueIDs}
|
|
|
resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
@@ -522,8 +544,8 @@ func (s *PlaneService) AddIssuesToCycle(cycleID string, issueIDs []string) ([]by
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) RemoveIssueFromCycle(cycleID, issueID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/%s/", s.WorkspaceSlug, s.ProjectId, cycleID, issueID)
|
|
|
+func (s *PlaneService) RemoveIssueFromCycle(workspaceSlug, projectId, cycleID, issueID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/%s/", workspaceSlug, projectId, cycleID, issueID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -534,8 +556,8 @@ func (s *PlaneService) RemoveIssueFromCycle(cycleID, issueID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ArchiveCycle(cycleID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/archive/", s.WorkspaceSlug, s.ProjectId, cycleID)
|
|
|
+func (s *PlaneService) ArchiveCycle(workspaceSlug, projectId, cycleID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/archive/", workspaceSlug, projectId, cycleID)
|
|
|
resp, err := s.Client.Post(url, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -546,8 +568,8 @@ func (s *PlaneService) ArchiveCycle(cycleID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UnarchiveCycle(cycleID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/archive/", s.WorkspaceSlug, s.ProjectId, cycleID)
|
|
|
+func (s *PlaneService) UnarchiveCycle(workspaceSlug, projectId, cycleID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/archive/", workspaceSlug, projectId, cycleID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -558,10 +580,10 @@ func (s *PlaneService) UnarchiveCycle(cycleID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Module 便捷方法 ============
|
|
|
+// ============ Module 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) ListModules() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) ListModules(workspaceSlug, projectId string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -572,8 +594,8 @@ func (s *PlaneService) ListModules() ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetModule(moduleID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/", s.WorkspaceSlug, s.ProjectId, moduleID)
|
|
|
+func (s *PlaneService) GetModule(workspaceSlug, projectId, moduleID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/", workspaceSlug, projectId, moduleID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -584,8 +606,8 @@ func (s *PlaneService) GetModule(moduleID string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateModule(data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) CreateModule(workspaceSlug, projectId string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Post(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -596,8 +618,8 @@ func (s *PlaneService) CreateModule(data map[string]interface{}) ([]byte, error)
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateModule(moduleID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/", s.WorkspaceSlug, s.ProjectId, moduleID)
|
|
|
+func (s *PlaneService) UpdateModule(workspaceSlug, projectId, moduleID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/", workspaceSlug, projectId, moduleID)
|
|
|
resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -608,8 +630,8 @@ func (s *PlaneService) UpdateModule(moduleID string, data map[string]interface{}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteModule(moduleID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/", s.WorkspaceSlug, s.ProjectId, moduleID)
|
|
|
+func (s *PlaneService) DeleteModule(workspaceSlug, projectId, moduleID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/", workspaceSlug, projectId, moduleID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -620,8 +642,8 @@ func (s *PlaneService) DeleteModule(moduleID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ListModuleIssues(moduleID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/module-issues/", s.WorkspaceSlug, s.ProjectId, moduleID)
|
|
|
+func (s *PlaneService) ListModuleIssues(workspaceSlug, projectId, moduleID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/module-issues/", workspaceSlug, projectId, moduleID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -632,8 +654,8 @@ func (s *PlaneService) ListModuleIssues(moduleID string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) AddIssuesToModule(moduleID string, issueIDs []string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/module-issues/", s.WorkspaceSlug, s.ProjectId, moduleID)
|
|
|
+func (s *PlaneService) AddIssuesToModule(workspaceSlug, projectId, moduleID string, issueIDs []string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/module-issues/", workspaceSlug, projectId, moduleID)
|
|
|
payload := map[string]interface{}{"issues": issueIDs}
|
|
|
resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
@@ -645,8 +667,8 @@ func (s *PlaneService) AddIssuesToModule(moduleID string, issueIDs []string) ([]
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) RemoveIssueFromModule(moduleID, issueID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/module-issues/%s/", s.WorkspaceSlug, s.ProjectId, moduleID, issueID)
|
|
|
+func (s *PlaneService) RemoveIssueFromModule(workspaceSlug, projectId, moduleID, issueID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/module-issues/%s/", workspaceSlug, projectId, moduleID, issueID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -657,8 +679,8 @@ func (s *PlaneService) RemoveIssueFromModule(moduleID, issueID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ArchiveModule(moduleID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/archive/", s.WorkspaceSlug, s.ProjectId, moduleID)
|
|
|
+func (s *PlaneService) ArchiveModule(workspaceSlug, projectId, moduleID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/archive/", workspaceSlug, projectId, moduleID)
|
|
|
resp, err := s.Client.Post(url, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -669,8 +691,8 @@ func (s *PlaneService) ArchiveModule(moduleID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UnarchiveModule(moduleID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/archive/", s.WorkspaceSlug, s.ProjectId, moduleID)
|
|
|
+func (s *PlaneService) UnarchiveModule(workspaceSlug, projectId, moduleID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/modules/%s/archive/", workspaceSlug, projectId, moduleID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -681,10 +703,10 @@ func (s *PlaneService) UnarchiveModule(moduleID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Label 便捷方法 ============
|
|
|
+// ============ Label 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) ListLabels() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) ListLabels(workspaceSlug, projectId string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -695,8 +717,8 @@ func (s *PlaneService) ListLabels() ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetLabel(labelID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/%s/", s.WorkspaceSlug, s.ProjectId, labelID)
|
|
|
+func (s *PlaneService) GetLabel(workspaceSlug, projectId, labelID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/%s/", workspaceSlug, projectId, labelID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -707,8 +729,8 @@ func (s *PlaneService) GetLabel(labelID string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateLabel(name, color string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) CreateLabel(workspaceSlug, projectId, name, color string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/", workspaceSlug, projectId)
|
|
|
payload := map[string]interface{}{"name": name, "color": color}
|
|
|
resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
@@ -720,8 +742,8 @@ func (s *PlaneService) CreateLabel(name, color string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateLabel(labelID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/%s/", s.WorkspaceSlug, s.ProjectId, labelID)
|
|
|
+func (s *PlaneService) UpdateLabel(workspaceSlug, projectId, labelID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/%s/", workspaceSlug, projectId, labelID)
|
|
|
resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -732,8 +754,8 @@ func (s *PlaneService) UpdateLabel(labelID string, data map[string]interface{})
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteLabel(labelID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/%s/", s.WorkspaceSlug, s.ProjectId, labelID)
|
|
|
+func (s *PlaneService) DeleteLabel(workspaceSlug, projectId, labelID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/labels/%s/", workspaceSlug, projectId, labelID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -744,10 +766,10 @@ func (s *PlaneService) DeleteLabel(labelID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ State 便捷方法 ============
|
|
|
+// ============ State 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) ListStates() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) ListStates(workspaceSlug, projectId string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -758,8 +780,8 @@ func (s *PlaneService) ListStates() ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetState(stateID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/", s.WorkspaceSlug, s.ProjectId, stateID)
|
|
|
+func (s *PlaneService) GetState(workspaceSlug, projectId, stateID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/", workspaceSlug, projectId, stateID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -770,8 +792,8 @@ func (s *PlaneService) GetState(stateID string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateState(name, color, group string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+func (s *PlaneService) CreateState(workspaceSlug, projectId, name, color, group string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/", workspaceSlug, projectId)
|
|
|
payload := map[string]interface{}{"name": name, "color": color, "group": group}
|
|
|
resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
@@ -783,8 +805,8 @@ func (s *PlaneService) CreateState(name, color, group string) ([]byte, error) {
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateState(stateID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/", s.WorkspaceSlug, s.ProjectId, stateID)
|
|
|
+func (s *PlaneService) UpdateState(workspaceSlug, projectId, stateID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/", workspaceSlug, projectId, stateID)
|
|
|
resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
@@ -795,8 +817,8 @@ func (s *PlaneService) UpdateState(stateID string, data map[string]interface{})
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteState(stateID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/", s.WorkspaceSlug, s.ProjectId, stateID)
|
|
|
+func (s *PlaneService) DeleteState(workspaceSlug, projectId, stateID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/", workspaceSlug, projectId, stateID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -807,8 +829,8 @@ func (s *PlaneService) DeleteState(stateID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) MarkStateDefault(stateID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/default/", s.WorkspaceSlug, s.ProjectId, stateID)
|
|
|
+func (s *PlaneService) MarkStateDefault(workspaceSlug, projectId, stateID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/states/%s/default/", workspaceSlug, projectId, stateID)
|
|
|
resp, err := s.Client.Post(url, nil)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -819,470 +841,429 @@ func (s *PlaneService) MarkStateDefault(stateID string) error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Comment 便捷方法 ============
|
|
|
+// ============ Page 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) ListComments(issueID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
+func (s *PlaneService) ListPages(workspaceSlug, projectId string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/", workspaceSlug, projectId)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListComments 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListPages 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetComment(issueID, commentID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/%s/", s.WorkspaceSlug, s.ProjectId, issueID, commentID)
|
|
|
+func (s *PlaneService) GetPage(workspaceSlug, projectId, pageID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/", workspaceSlug, projectId, pageID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetComment 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("GetPage 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateComment(issueID, commentHTML string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- payload := map[string]interface{}{"comment_html": commentHTML}
|
|
|
- resp, err := s.Client.Post(url, payload)
|
|
|
+func (s *PlaneService) GetPageDescription(workspaceSlug, projectId, pageID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/description/", workspaceSlug, projectId, pageID)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateComment 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("GetPageDescription 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateComment(issueID, commentID, commentHTML string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/%s/", s.WorkspaceSlug, s.ProjectId, issueID, commentID)
|
|
|
- payload := map[string]interface{}{"comment_html": commentHTML}
|
|
|
- resp, err := s.Client.Patch(url, payload)
|
|
|
+func (s *PlaneService) CreatePage(workspaceSlug, projectId string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/", workspaceSlug, projectId)
|
|
|
+ resp, err := s.Client.Post(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateComment 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("CreatePage 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ }
|
|
|
+ return resp.Body, nil
|
|
|
+}
|
|
|
+
|
|
|
+func (s *PlaneService) UpdatePage(workspaceSlug, projectId, pageID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/", workspaceSlug, projectId, pageID)
|
|
|
+ resp, err := s.Client.Patch(url, data)
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if !IsSuccess(resp.StatusCode) {
|
|
|
+ return nil, fmt.Errorf("UpdatePage 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteComment(issueID, commentID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/%s/", s.WorkspaceSlug, s.ProjectId, issueID, commentID)
|
|
|
+func (s *PlaneService) DeletePage(workspaceSlug, projectId, pageID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/", workspaceSlug, projectId, pageID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteComment 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("DeletePage 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Link 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) ListIssueLinks(issueID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
+func (s *PlaneService) ArchivePage(workspaceSlug, projectId, pageID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/archive/", workspaceSlug, projectId, pageID)
|
|
|
+ resp, err := s.Client.Post(url, nil)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListIssueLinks 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("ArchivePage 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return resp.Body, nil
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateIssueLink(issueID, linkURL, title string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- payload := map[string]interface{}{"url": linkURL, "title": title}
|
|
|
- resp, err := s.Client.Post(url, payload)
|
|
|
+func (s *PlaneService) UnarchivePage(workspaceSlug, projectId, pageID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/archive/", workspaceSlug, projectId, pageID)
|
|
|
+ resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
- return nil, err
|
|
|
+ return err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateIssueLink 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return fmt.Errorf("UnarchivePage 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return resp.Body, nil
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateIssueLink(issueID, linkID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/%s/", s.WorkspaceSlug, s.ProjectId, issueID, linkID)
|
|
|
- resp, err := s.Client.Patch(url, data)
|
|
|
+// ============ Comment 方法 ============
|
|
|
+
|
|
|
+func (s *PlaneService) ListComments(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/", workspaceSlug, projectId, issueID)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateIssueLink 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("ListComments 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteIssueLink(issueID, linkID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/%s/", s.WorkspaceSlug, s.ProjectId, issueID, linkID)
|
|
|
- resp, err := s.Client.Delete(url)
|
|
|
+func (s *PlaneService) GetComment(workspaceSlug, projectId, issueID, commentID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/%s/", workspaceSlug, projectId, issueID, commentID)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return nil, err
|
|
|
}
|
|
|
- if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteIssueLink 失败: %s", resp.Status)
|
|
|
+ if !IsSuccess(resp.StatusCode) {
|
|
|
+ return nil, fmt.Errorf("GetComment 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return nil
|
|
|
+ return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-// ============ Relation 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) ListIssueRelations(issueID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/relations/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
+func (s *PlaneService) CreateComment(workspaceSlug, projectId, issueID, commentHTML string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/", workspaceSlug, projectId, issueID)
|
|
|
+ payload := map[string]interface{}{"comment_html": commentHTML}
|
|
|
+ resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListIssueRelations 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("CreateComment 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateIssueRelation(issueID, relationType string, relatedIDs []string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/relations/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- payload := map[string]interface{}{"relation_type": relationType, "related_issues": relatedIDs}
|
|
|
- resp, err := s.Client.Post(url, payload)
|
|
|
+func (s *PlaneService) UpdateComment(workspaceSlug, projectId, issueID, commentID, commentHTML string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/%s/", workspaceSlug, projectId, issueID, commentID)
|
|
|
+ payload := map[string]interface{}{"comment_html": commentHTML}
|
|
|
+ resp, err := s.Client.Patch(url, payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateIssueRelation 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("UpdateComment 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) RemoveIssueRelation(issueID, relationType, relatedID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/relations/%s/%s/", s.WorkspaceSlug, s.ProjectId, issueID, relationType, relatedID)
|
|
|
+func (s *PlaneService) DeleteComment(workspaceSlug, projectId, issueID, commentID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/comments/%s/", workspaceSlug, projectId, issueID, commentID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("RemoveIssueRelation 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("DeleteComment 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Sticky 便捷方法 ============
|
|
|
+// ============ Link 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) ListStickies() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/stickies/", s.WorkspaceSlug)
|
|
|
+func (s *PlaneService) ListIssueLinks(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/", workspaceSlug, projectId, issueID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListStickies 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- return resp.Body, nil
|
|
|
-}
|
|
|
-
|
|
|
-func (s *PlaneService) GetSticky(stickyID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/stickies/%s/", s.WorkspaceSlug, stickyID)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
- if err != nil {
|
|
|
- return nil, err
|
|
|
- }
|
|
|
- if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetSticky 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListIssueLinks 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) CreateSticky(data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/stickies/", s.WorkspaceSlug)
|
|
|
- resp, err := s.Client.Post(url, data)
|
|
|
+func (s *PlaneService) CreateIssueLink(workspaceSlug, projectId, issueID, linkURL, title string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/", workspaceSlug, projectId, issueID)
|
|
|
+ payload := map[string]interface{}{"url": linkURL, "title": title}
|
|
|
+ resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateSticky 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("CreateIssueLink 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateSticky(stickyID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/stickies/%s/", s.WorkspaceSlug, stickyID)
|
|
|
+func (s *PlaneService) UpdateIssueLink(workspaceSlug, projectId, issueID, linkID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/%s/", workspaceSlug, projectId, issueID, linkID)
|
|
|
resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateSticky 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("UpdateIssueLink 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeleteSticky(stickyID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/stickies/%s/", s.WorkspaceSlug, stickyID)
|
|
|
+func (s *PlaneService) DeleteIssueLink(workspaceSlug, projectId, issueID, linkID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/links/%s/", workspaceSlug, projectId, issueID, linkID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteSticky 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("DeleteIssueLink 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-// ============ Intake 补充方法 ============
|
|
|
+// ============ Relation 方法 ============
|
|
|
|
|
|
-func (s *PlaneService) UpdateIntakeIssue(issueID string, data map[string]any) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/%s/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Patch(url, data)
|
|
|
+func (s *PlaneService) ListIssueRelations(workspaceSlug, projectId, issueID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/relations/", workspaceSlug, projectId, issueID)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateIntakeIssue 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListIssueRelations 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) AcceptIntakeIssue(issueID string) ([]byte, error) {
|
|
|
- return s.UpdateIntakeIssue(issueID, map[string]any{"status": 1})
|
|
|
-}
|
|
|
-
|
|
|
-func (s *PlaneService) RejectIntakeIssue(issueID string) ([]byte, error) {
|
|
|
- return s.UpdateIntakeIssue(issueID, map[string]any{"status": -1})
|
|
|
-}
|
|
|
-
|
|
|
-func (s *PlaneService) DeleteIntakeIssue(issueID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/intake-issues/%s/", s.WorkspaceSlug, s.ProjectId, issueID)
|
|
|
- resp, err := s.Client.Delete(url)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeleteIntakeIssue 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-// ============ Asset 补充方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) CreateProjectAsset(fileName, mimeType string, size int64, entityType string) (*AssetUploadResult, error) {
|
|
|
- url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- payload := map[string]interface{}{
|
|
|
- "name": fileName, "type": mimeType, "size": size,
|
|
|
- "entity_type": entityType, "entity_identifier": "",
|
|
|
- }
|
|
|
+func (s *PlaneService) CreateIssueRelation(workspaceSlug, projectId, issueID, relationType string, relatedIDs []string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/relations/", workspaceSlug, projectId, issueID)
|
|
|
+ payload := map[string]interface{}{"relation_type": relationType, "related_issues": relatedIDs}
|
|
|
resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreateProjectAsset 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- var result AssetUploadResult
|
|
|
- if err := json.Unmarshal(resp.Body, &result); err != nil {
|
|
|
- return nil, fmt.Errorf("解析响应失败: %w", err)
|
|
|
+ return nil, fmt.Errorf("CreateIssueRelation 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
- return &result, nil
|
|
|
+ return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ConfirmProjectAssetUpload(assetID string) error {
|
|
|
- url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", s.WorkspaceSlug, s.ProjectId, assetID)
|
|
|
- resp, err := s.Client.Patch(url, map[string]interface{}{})
|
|
|
+func (s *PlaneService) RemoveIssueRelation(workspaceSlug, projectId, issueID, relationType, relatedID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/relations/%s/%s/", workspaceSlug, projectId, issueID, relationType, relatedID)
|
|
|
+ resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- if resp.StatusCode != 204 && !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("ConfirmProjectAssetUpload 失败: %s", resp.Status)
|
|
|
+ if resp.StatusCode != 204 {
|
|
|
+ return fmt.Errorf("RemoveIssueRelation 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetProjectAsset(assetID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/assets/v2/workspaces/%s/projects/%s/%s/", s.WorkspaceSlug, s.ProjectId, assetID)
|
|
|
+// ============ Member 方法 ============
|
|
|
+
|
|
|
+func (s *PlaneService) ListWorkspaceMembers(workspaceSlug string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/members/", workspaceSlug)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
+ if !IsSuccess(resp.StatusCode) {
|
|
|
+ return nil, fmt.Errorf("ListWorkspaceMembers 失败: %s", resp.Status)
|
|
|
+ }
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-// ============ Page 补充方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) CreatePage(data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- resp, err := s.Client.Post(url, data)
|
|
|
+func (s *PlaneService) GetWorkspaceMember(workspaceSlug, memberID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/members/%s/", workspaceSlug, memberID)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("CreatePage 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("GetWorkspaceMember 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdatePage(pageID string, data map[string]interface{}) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/", s.WorkspaceSlug, s.ProjectId, pageID)
|
|
|
- resp, err := s.Client.Patch(url, data)
|
|
|
+func (s *PlaneService) UpdateWorkspaceMemberRole(workspaceSlug, memberID string, role int) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/members/%s/", workspaceSlug, memberID)
|
|
|
+ payload := map[string]interface{}{"role": role}
|
|
|
+ resp, err := s.Client.Patch(url, payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdatePage 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("UpdateWorkspaceMemberRole 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) DeletePage(pageID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/", s.WorkspaceSlug, s.ProjectId, pageID)
|
|
|
+func (s *PlaneService) RemoveWorkspaceMember(workspaceSlug, memberID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/members/%s/", workspaceSlug, memberID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("DeletePage 失败: %s", resp.Status)
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (s *PlaneService) ArchivePage(pageID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/archive/", s.WorkspaceSlug, s.ProjectId, pageID)
|
|
|
- resp, err := s.Client.Post(url, nil)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- if !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("ArchivePage 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("RemoveWorkspaceMember 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UnarchivePage(pageID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/pages/%s/archive/", s.WorkspaceSlug, s.ProjectId, pageID)
|
|
|
- resp, err := s.Client.Delete(url)
|
|
|
+func (s *PlaneService) ListProjectMembers(workspaceSlug, projectId string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/", workspaceSlug, projectId)
|
|
|
+ resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return fmt.Errorf("UnarchivePage 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListProjectMembers 失败: %s", resp.Status)
|
|
|
}
|
|
|
- return nil
|
|
|
+ return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-// ============ Member 便捷方法 ============
|
|
|
-
|
|
|
-func (s *PlaneService) ListWorkspaceMembers() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/members/", s.WorkspaceSlug)
|
|
|
+func (s *PlaneService) GetProjectMember(workspaceSlug, projectId, memberID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/%s/", workspaceSlug, projectId, memberID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListWorkspaceMembers 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("GetProjectMember 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetWorkspaceMember(memberID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/members/%s/", s.WorkspaceSlug, memberID)
|
|
|
- resp, err := s.Client.Get(url)
|
|
|
+func (s *PlaneService) AddProjectMember(workspaceSlug, projectId, memberID string, role int) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/", workspaceSlug, projectId)
|
|
|
+ payload := map[string]interface{}{"member": memberID, "role": role}
|
|
|
+ resp, err := s.Client.Post(url, payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetWorkspaceMember 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("AddProjectMember 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateWorkspaceMemberRole(memberID string, role int) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/members/%s/", s.WorkspaceSlug, memberID)
|
|
|
+func (s *PlaneService) UpdateProjectMemberRole(workspaceSlug, projectId, memberID string, role int) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/%s/", workspaceSlug, projectId, memberID)
|
|
|
payload := map[string]interface{}{"role": role}
|
|
|
resp, err := s.Client.Patch(url, payload)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateWorkspaceMemberRole 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("UpdateProjectMemberRole 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) RemoveWorkspaceMember(memberID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/members/%s/", s.WorkspaceSlug, memberID)
|
|
|
+func (s *PlaneService) RemoveProjectMember(workspaceSlug, projectId, memberID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/%s/", workspaceSlug, projectId, memberID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("RemoveWorkspaceMember 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("RemoveProjectMember 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) ListProjectMembers() ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/", s.WorkspaceSlug, s.ProjectId)
|
|
|
+// ============ Sticky 方法 ============
|
|
|
+
|
|
|
+func (s *PlaneService) ListStickies(workspaceSlug string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/stickies/", workspaceSlug)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("ListProjectMembers 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("ListStickies 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) GetProjectMember(memberID string) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/%s/", s.WorkspaceSlug, s.ProjectId, memberID)
|
|
|
+func (s *PlaneService) GetSticky(workspaceSlug, stickyID string) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/stickies/%s/", workspaceSlug, stickyID)
|
|
|
resp, err := s.Client.Get(url)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("GetProjectMember 失败: %s", resp.Status)
|
|
|
+ return nil, fmt.Errorf("GetSticky 失败: %s", resp.Status)
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) AddProjectMember(memberID string, role int) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/", s.WorkspaceSlug, s.ProjectId)
|
|
|
- payload := map[string]interface{}{"member": memberID, "role": role}
|
|
|
- resp, err := s.Client.Post(url, payload)
|
|
|
+func (s *PlaneService) CreateSticky(workspaceSlug string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/stickies/", workspaceSlug)
|
|
|
+ resp, err := s.Client.Post(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("AddProjectMember 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("CreateSticky 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) UpdateProjectMemberRole(memberID string, role int) ([]byte, error) {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/%s/", s.WorkspaceSlug, s.ProjectId, memberID)
|
|
|
- payload := map[string]interface{}{"role": role}
|
|
|
- resp, err := s.Client.Patch(url, payload)
|
|
|
+func (s *PlaneService) UpdateSticky(workspaceSlug, stickyID string, data map[string]interface{}) ([]byte, error) {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/stickies/%s/", workspaceSlug, stickyID)
|
|
|
+ resp, err := s.Client.Patch(url, data)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
if !IsSuccess(resp.StatusCode) {
|
|
|
- return nil, fmt.Errorf("UpdateProjectMemberRole 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
+ return nil, fmt.Errorf("UpdateSticky 失败: %s, body=%s", resp.Status, string(resp.Body))
|
|
|
}
|
|
|
return resp.Body, nil
|
|
|
}
|
|
|
|
|
|
-func (s *PlaneService) RemoveProjectMember(memberID string) error {
|
|
|
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/members/%s/", s.WorkspaceSlug, s.ProjectId, memberID)
|
|
|
+func (s *PlaneService) DeleteSticky(workspaceSlug, stickyID string) error {
|
|
|
+ url := fmt.Sprintf("/api/workspaces/%s/stickies/%s/", workspaceSlug, stickyID)
|
|
|
resp, err := s.Client.Delete(url)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
if resp.StatusCode != 204 {
|
|
|
- return fmt.Errorf("RemoveProjectMember 失败: %s", resp.Status)
|
|
|
+ return fmt.Errorf("DeleteSticky 失败: %s", resp.Status)
|
|
|
}
|
|
|
return nil
|
|
|
-}
|
|
|
+}
|