package plane_v2 import ( "fmt" "go.uber.org/zap" ) // ==================== Issue (Work Item) API ==================== // ListIssues 列出工作项 func ListIssues(slug, projectID string) ([]byte, error) { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", slug, projectID) resp, err := planeWebGet(url) if err != nil { zap.L().Error("[PlaneWeb] ListIssues 请求失败", zap.Error(err)) return nil, err } if !isWebSuccess(resp.StatusCode) { zap.L().Error("[PlaneWeb] ListIssues 返回错误", zap.String("status", resp.Status)) return nil, fmt.Errorf("ListIssues 失败: %s", resp.Status) } return resp.Body, nil } // CreateIssue 创建工作项 func CreateIssue(slug, projectID string, data map[string]interface{}) ([]byte, error) { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/", slug, projectID) resp, err := planeWebPost(url, data) if err != nil { zap.L().Error("[PlaneWeb] CreateIssue 请求失败", zap.Error(err)) return nil, err } if resp.StatusCode != 201 { zap.L().Error("[PlaneWeb] CreateIssue 返回错误", zap.String("status", resp.Status), zap.String("body", string(resp.Body)), ) return nil, fmt.Errorf("CreateIssue 失败: %s", resp.Status) } return resp.Body, nil } // GetIssue 获取工作项详情 func GetIssue(slug, projectID, issueID string) ([]byte, error) { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", slug, projectID, issueID) resp, err := planeWebGet(url) if err != nil { zap.L().Error("[PlaneWeb] GetIssue 请求失败", zap.Error(err)) return nil, err } if !isWebSuccess(resp.StatusCode) { zap.L().Error("[PlaneWeb] GetIssue 返回错误", zap.String("status", resp.Status)) return nil, fmt.Errorf("GetIssue 失败: %s", resp.Status) } return resp.Body, nil } // UpdateIssue 更新工作项 func UpdateIssue(slug, projectID, issueID string, data map[string]interface{}) ([]byte, error) { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", slug, projectID, issueID) resp, err := planeWebPatch(url, data) if err != nil { zap.L().Error("[PlaneWeb] UpdateIssue 请求失败", zap.Error(err)) return nil, err } if !isWebSuccess(resp.StatusCode) { zap.L().Error("[PlaneWeb] UpdateIssue 返回错误", zap.String("status", resp.Status), zap.String("body", string(resp.Body)), ) return nil, fmt.Errorf("UpdateIssue 失败: %s", resp.Status) } return resp.Body, nil } // DeleteIssue 删除工作项 func DeleteIssue(slug, projectID, issueID string) error { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/", slug, projectID, issueID) resp, err := planeWebDelete(url) if err != nil { zap.L().Error("[PlaneWeb] DeleteIssue 请求失败", zap.Error(err)) return err } if resp.StatusCode != 204 { zap.L().Error("[PlaneWeb] DeleteIssue 返回错误", zap.String("status", resp.Status)) return fmt.Errorf("DeleteIssue 失败: %s", resp.Status) } return nil } // GetSubIssues 获取子工作项 func GetSubIssues(slug, projectID, issueID string) ([]byte, error) { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/sub-issues/", slug, projectID, issueID) resp, err := planeWebGet(url) if err != nil { zap.L().Error("[PlaneWeb] GetSubIssues 请求失败", zap.Error(err)) return nil, err } if !isWebSuccess(resp.StatusCode) { zap.L().Error("[PlaneWeb] GetSubIssues 返回错误", zap.String("status", resp.Status)) return nil, fmt.Errorf("GetSubIssues 失败: %s", resp.Status) } return resp.Body, nil } // ArchiveIssue 归档工作项 func ArchiveIssue(slug, projectID, issueID string) error { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", slug, projectID, issueID) resp, err := planeWebPost(url, map[string]interface{}{}) if err != nil { zap.L().Error("[PlaneWeb] ArchiveIssue 请求失败", zap.Error(err)) return err } if !isWebSuccess(resp.StatusCode) { zap.L().Error("[PlaneWeb] ArchiveIssue 返回错误", zap.String("status", resp.Status)) return fmt.Errorf("ArchiveIssue 失败: %s", resp.Status) } return nil } // UnarchiveIssue 取消归档工作项 func UnarchiveIssue(slug, projectID, issueID string) error { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/archive/", slug, projectID, issueID) resp, err := planeWebDelete(url) if err != nil { zap.L().Error("[PlaneWeb] UnarchiveIssue 请求失败", zap.Error(err)) return err } if !isWebSuccess(resp.StatusCode) { zap.L().Error("[PlaneWeb] UnarchiveIssue 返回错误", zap.String("status", resp.Status)) return fmt.Errorf("UnarchiveIssue 失败: %s", resp.Status) } return nil } // GetIssueActivity 获取工作项活动历史 func GetIssueActivity(slug, projectID, issueID string) ([]byte, error) { url := fmt.Sprintf("/api/workspaces/%s/projects/%s/issues/%s/history/", slug, projectID, issueID) resp, err := planeWebGet(url) if err != nil { zap.L().Error("[PlaneWeb] GetIssueActivity 请求失败", zap.Error(err)) return nil, err } if !isWebSuccess(resp.StatusCode) { zap.L().Error("[PlaneWeb] GetIssueActivity 返回错误", zap.String("status", resp.Status)) return nil, fmt.Errorf("GetIssueActivity 失败: %s", resp.Status) } return resp.Body, nil } // ListCurrentIssues 列出当前项目下的工作项 func ListCurrentIssues() ([]byte, error) { return ListIssues(webWorkspaceSlug, webProjectId) } // CreateCurrentIssue 在当前项目下创建工作项 func CreateCurrentIssue(data map[string]interface{}) ([]byte, error) { return CreateIssue(webWorkspaceSlug, webProjectId, data) }