| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- package plane_v2
- import (
- "fmt"
- "go.uber.org/zap"
- )
- // ==================== Cycle API ====================
- // ListCycles 列出迭代
- func ListCycles(slug, projectID string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/", slug, projectID)
- resp, err := planeWebGet(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] ListCycles 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] ListCycles 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("ListCycles 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // CreateCycle 创建迭代
- func CreateCycle(slug, projectID string, data map[string]interface{}) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/", slug, projectID)
- resp, err := planeWebPost(url, data)
- if err != nil {
- zap.L().Error("[PlaneWeb] CreateCycle 请求失败", zap.Error(err))
- return nil, err
- }
- if resp.StatusCode != 201 {
- zap.L().Error("[PlaneWeb] CreateCycle 返回错误",
- zap.String("status", resp.Status),
- zap.String("body", string(resp.Body)),
- )
- return nil, fmt.Errorf("CreateCycle 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // GetCycle 获取迭代详情
- func GetCycle(slug, projectID, cycleID string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", slug, projectID, cycleID)
- resp, err := planeWebGet(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] GetCycle 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] GetCycle 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("GetCycle 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // UpdateCycle 更新迭代
- func UpdateCycle(slug, projectID, cycleID string, data map[string]interface{}) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", slug, projectID, cycleID)
- resp, err := planeWebPatch(url, data)
- if err != nil {
- zap.L().Error("[PlaneWeb] UpdateCycle 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] UpdateCycle 返回错误",
- zap.String("status", resp.Status),
- zap.String("body", string(resp.Body)),
- )
- return nil, fmt.Errorf("UpdateCycle 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // DeleteCycle 删除迭代
- func DeleteCycle(slug, projectID, cycleID string) error {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/", slug, projectID, cycleID)
- resp, err := planeWebDelete(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] DeleteCycle 请求失败", zap.Error(err))
- return err
- }
- if resp.StatusCode != 204 {
- zap.L().Error("[PlaneWeb] DeleteCycle 返回错误", zap.String("status", resp.Status))
- return fmt.Errorf("DeleteCycle 失败: %s", resp.Status)
- }
- return nil
- }
- // ListCycleIssues 列出迭代中的工作项
- func ListCycleIssues(slug, projectID, cycleID string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/", slug, projectID, cycleID)
- resp, err := planeWebGet(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] ListCycleIssues 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] ListCycleIssues 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("ListCycleIssues 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // AddIssuesToCycle 添加工作项到迭代
- func AddIssuesToCycle(slug, projectID, cycleID string, issueIDs []string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/", slug, projectID, cycleID)
- payload := map[string]interface{}{
- "issues": issueIDs,
- }
- resp, err := planeWebPost(url, payload)
- if err != nil {
- zap.L().Error("[PlaneWeb] AddIssuesToCycle 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] AddIssuesToCycle 返回错误",
- zap.String("status", resp.Status),
- zap.String("body", string(resp.Body)),
- )
- return nil, fmt.Errorf("AddIssuesToCycle 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // RemoveIssueFromCycle 从迭代移除工作项
- func RemoveIssueFromCycle(slug, projectID, cycleID, issueID string) error {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/cycle-issues/%s/", slug, projectID, cycleID, issueID)
- resp, err := planeWebDelete(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] RemoveIssueFromCycle 请求失败", zap.Error(err))
- return err
- }
- if resp.StatusCode != 204 {
- zap.L().Error("[PlaneWeb] RemoveIssueFromCycle 返回错误", zap.String("status", resp.Status))
- return fmt.Errorf("RemoveIssueFromCycle 失败: %s", resp.Status)
- }
- return nil
- }
- // TransferCycleIssues 转移未完成工作项到另一迭代
- func TransferCycleIssues(slug, projectID, cycleID, newCycleID string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/transfer-issues/", slug, projectID, cycleID)
- payload := map[string]interface{}{
- "new_cycle_id": newCycleID,
- }
- resp, err := planeWebPost(url, payload)
- if err != nil {
- zap.L().Error("[PlaneWeb] TransferCycleIssues 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] TransferCycleIssues 返回错误",
- zap.String("status", resp.Status),
- zap.String("body", string(resp.Body)),
- )
- return nil, fmt.Errorf("TransferCycleIssues 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // ArchiveCycle 归档迭代
- func ArchiveCycle(slug, projectID, cycleID string) error {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/archive/", slug, projectID, cycleID)
- resp, err := planeWebPost(url, map[string]interface{}{})
- if err != nil {
- zap.L().Error("[PlaneWeb] ArchiveCycle 请求失败", zap.Error(err))
- return err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] ArchiveCycle 返回错误", zap.String("status", resp.Status))
- return fmt.Errorf("ArchiveCycle 失败: %s", resp.Status)
- }
- return nil
- }
- // ListArchivedCycles 列出已归档迭代
- func ListArchivedCycles(slug, projectID string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/archived-cycles/", slug, projectID)
- resp, err := planeWebGet(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] ListArchivedCycles 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] ListArchivedCycles 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("ListArchivedCycles 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // UnarchiveCycle 取消归档迭代
- func UnarchiveCycle(slug, projectID, cycleID string) error {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/archived-cycles/%s/", slug, projectID, cycleID)
- resp, err := planeWebDelete(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] UnarchiveCycle 请求失败", zap.Error(err))
- return err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] UnarchiveCycle 返回错误", zap.String("status", resp.Status))
- return fmt.Errorf("UnarchiveCycle 失败: %s", resp.Status)
- }
- return nil
- }
- // GetCycleProgress 获取迭代进度
- func GetCycleProgress(slug, projectID, cycleID string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/progress/", slug, projectID, cycleID)
- resp, err := planeWebGet(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] GetCycleProgress 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] GetCycleProgress 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("GetCycleProgress 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // GetCycleAnalytics 获取迭代分析
- func GetCycleAnalytics(slug, projectID, cycleID string) ([]byte, error) {
- url := fmt.Sprintf("/api/workspaces/%s/projects/%s/cycles/%s/analytics/", slug, projectID, cycleID)
- resp, err := planeWebGet(url)
- if err != nil {
- zap.L().Error("[PlaneWeb] GetCycleAnalytics 请求失败", zap.Error(err))
- return nil, err
- }
- if !isWebSuccess(resp.StatusCode) {
- zap.L().Error("[PlaneWeb] GetCycleAnalytics 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("GetCycleAnalytics 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
|