diff --git a/.testdata/api/iteration/update_iteration.json b/.testdata/api/iteration/update_iteration.json new file mode 100644 index 0000000..c4a621e --- /dev/null +++ b/.testdata/api/iteration/update_iteration.json @@ -0,0 +1,84 @@ +{ + "status": 1, + "data": { + "Iteration": { + "id": "11111222001002235", + "name": "2025 年 M1-迭代", + "workspace_id": "111222", + "startdate": "2025-01-01", + "enddate": "2025-01-31", + "status": "open", + "release_id": null, + "description": null, + "creator": "creator name", + "created": "2024-12-27 17:04:43", + "modified": "2024-12-27 17:04:43", + "completed": null, + "entity_type": "iteration", + "parent_id": "0", + "ancestor_id": "11111222001002235", + "path": "11111222001002235:", + "workitem_type_id": "11111222001000098", + "templated_id": "11111222001000218", + "plan_app_id": "0", + "crucial_moment": "CrucialMoment", + "label": "", + "releaseowner": null, + "launchdate": null, + "notice": null, + "releasename": null, + "custom_field_1": null, + "custom_field_2": null, + "custom_field_3": null, + "custom_field_4": null, + "custom_field_5": null, + "custom_field_6": null, + "custom_field_7": null, + "custom_field_8": null, + "custom_field_9": null, + "custom_field_10": null, + "custom_field_11": "", + "custom_field_12": "", + "custom_field_13": "", + "custom_field_14": "", + "custom_field_15": "", + "custom_field_16": "", + "custom_field_17": "", + "custom_field_18": "", + "custom_field_19": "", + "custom_field_20": "", + "custom_field_21": "", + "custom_field_22": "", + "custom_field_23": "", + "custom_field_24": "", + "custom_field_25": "", + "custom_field_26": "", + "custom_field_27": "", + "custom_field_28": "", + "custom_field_29": "", + "custom_field_30": "", + "custom_field_31": "", + "custom_field_32": "", + "custom_field_33": "", + "custom_field_34": "", + "custom_field_35": "", + "custom_field_36": "", + "custom_field_37": "", + "custom_field_38": "", + "custom_field_39": "", + "custom_field_40": "", + "custom_field_41": "", + "custom_field_42": "", + "custom_field_43": "", + "custom_field_44": "", + "custom_field_45": "", + "custom_field_46": "", + "custom_field_47": "", + "custom_field_48": "", + "custom_field_49": "", + "custom_field_50": "", + "origin_name": "2025 年 M1-迭代" + } + }, + "info": "success" +} \ No newline at end of file diff --git a/api_iteration.go b/api_iteration.go index 1a9a688..fbd9f74 100644 --- a/api_iteration.go +++ b/api_iteration.go @@ -299,8 +299,8 @@ func (s *IterationService) GetIterationsCount( type GetIterationsCountRequest struct { ID *Multi[int] `url:"id,omitempty"` // ID 支持多ID查询 - Name *string `url:"name,omitempty"` // 标题 支持模糊匹配 WorkspaceID *int `url:"workspace_id,omitempty"` // 项目 ID + Name *string `url:"name,omitempty"` // 标题 支持模糊匹配 Description *string `url:"description,omitempty"` // 详细描述 StartDate *string `url:"startdate,omitempty"` // 开始时间 支持时间查询 EndDate *string `url:"enddate,omitempty"` // 结束时间 支持时间查询 @@ -363,7 +363,91 @@ type GetIterationsCountRequest struct { CustomField50 *string `url:"custom_field_50,omitempty"` // 自定义字段参数 } -// 更新迭代 +// UpdateIteration 更新迭代 +// +// https://open.tapd.cn/document/api-doc/API%E6%96%87%E6%A1%A3/api_reference/iteration/update_iteration.html +func (s *IterationService) UpdateIteration( + ctx context.Context, request *UpdateIterationRequest, opts ...RequestOption, +) (*Iteration, *Response, error) { + req, err := s.client.NewRequest(ctx, http.MethodPost, "iterations", request, opts) + if err != nil { + return nil, nil, err + } + + var item struct { + Iteration *Iteration `json:"Iteration"` + } + resp, err := s.client.Do(req, &item) + if err != nil { + return nil, resp, err + } + + return item.Iteration, resp, nil +} + +type UpdateIterationRequest struct { + ID *int `json:"id,omitempty"` // [必须] ID + WorkspaceID *int `json:"workspace_id,omitempty"` // [必须] 项目 ID + CurrentUser *string `json:"current_user,omitempty"` // [必须]变更人 + Name *string `json:"name,omitempty"` // 标题 支持模糊匹配 + Description *string `json:"description,omitempty"` // 详细描述 + StartDate *string `json:"startdate,omitempty"` // 开始时间 支持时间查询 + EndDate *string `json:"enddate,omitempty"` // 结束时间 支持时间查询 + Creator *string `json:"creator,omitempty"` // 创建人 + Status *string `json:"status,omitempty"` // 状态(系统状态 open/done,自定义状态可传中文) + Label *Enum[string] `json:"label,omitempty"` // 标签, 可传多个 + CustomField1 *string `json:"custom_field_1,omitempty"` // 自定义字段参数 + CustomField2 *string `json:"custom_field_2,omitempty"` // 自定义字段参数 + CustomField3 *string `json:"custom_field_3,omitempty"` // 自定义字段参数 + CustomField4 *string `json:"custom_field_4,omitempty"` // 自定义字段参数 + CustomField5 *string `json:"custom_field_5,omitempty"` // 自定义字段参数 + CustomField6 *string `json:"custom_field_6,omitempty"` // 自定义字段参数 + CustomField7 *string `json:"custom_field_7,omitempty"` // 自定义字段参数 + CustomField8 *string `json:"custom_field_8,omitempty"` // 自定义字段参数 + CustomField9 *string `json:"custom_field_9,omitempty"` // 自定义字段参数 + CustomField10 *string `json:"custom_field_10,omitempty"` // 自定义字段参数 + CustomField11 *string `json:"custom_field_11,omitempty"` // 自定义字段参数 + CustomField12 *string `json:"custom_field_12,omitempty"` // 自定义字段参数 + CustomField13 *string `json:"custom_field_13,omitempty"` // 自定义字段参数 + CustomField14 *string `json:"custom_field_14,omitempty"` // 自定义字段参数 + CustomField15 *string `json:"custom_field_15,omitempty"` // 自定义字段参数 + CustomField16 *string `json:"custom_field_16,omitempty"` // 自定义字段参数 + CustomField17 *string `json:"custom_field_17,omitempty"` // 自定义字段参数 + CustomField18 *string `json:"custom_field_18,omitempty"` // 自定义字段参数 + CustomField19 *string `json:"custom_field_19,omitempty"` // 自定义字段参数 + CustomField20 *string `json:"custom_field_20,omitempty"` // 自定义字段参数 + CustomField21 *string `json:"custom_field_21,omitempty"` // 自定义字段参数 + CustomField22 *string `json:"custom_field_22,omitempty"` // 自定义字段参数 + CustomField23 *string `json:"custom_field_23,omitempty"` // 自定义字段参数 + CustomField24 *string `json:"custom_field_24,omitempty"` // 自定义字段参数 + CustomField25 *string `json:"custom_field_25,omitempty"` // 自定义字段参数 + CustomField26 *string `json:"custom_field_26,omitempty"` // 自定义字段参数 + CustomField27 *string `json:"custom_field_27,omitempty"` // 自定义字段参数 + CustomField28 *string `json:"custom_field_28,omitempty"` // 自定义字段参数 + CustomField29 *string `json:"custom_field_29,omitempty"` // 自定义字段参数 + CustomField30 *string `json:"custom_field_30,omitempty"` // 自定义字段参数 + CustomField31 *string `json:"custom_field_31,omitempty"` // 自定义字段参数 + CustomField32 *string `json:"custom_field_32,omitempty"` // 自定义字段参数 + CustomField33 *string `json:"custom_field_33,omitempty"` // 自定义字段参数 + CustomField34 *string `json:"custom_field_34,omitempty"` // 自定义字段参数 + CustomField35 *string `json:"custom_field_35,omitempty"` // 自定义字段参数 + CustomField36 *string `json:"custom_field_36,omitempty"` // 自定义字段参数 + CustomField37 *string `json:"custom_field_37,omitempty"` // 自定义字段参数 + CustomField38 *string `json:"custom_field_38,omitempty"` // 自定义字段参数 + CustomField39 *string `json:"custom_field_39,omitempty"` // 自定义字段参数 + CustomField40 *string `json:"custom_field_40,omitempty"` // 自定义字段参数 + CustomField41 *string `json:"custom_field_41,omitempty"` // 自定义字段参数 + CustomField42 *string `json:"custom_field_42,omitempty"` // 自定义字段参数 + CustomField43 *string `json:"custom_field_43,omitempty"` // 自定义字段参数 + CustomField44 *string `json:"custom_field_44,omitempty"` // 自定义字段参数 + CustomField45 *string `json:"custom_field_45,omitempty"` // 自定义字段参数 + CustomField46 *string `json:"custom_field_46,omitempty"` // 自定义字段参数 + CustomField47 *string `json:"custom_field_47,omitempty"` // 自定义字段参数 + CustomField48 *string `json:"custom_field_48,omitempty"` // 自定义字段参数 + CustomField49 *string `json:"custom_field_49,omitempty"` // 自定义字段参数 + CustomField50 *string `json:"custom_field_50,omitempty"` // 自定义字段参数 +} + // 获取迭代变更历史 // 获取迭代仪表盘自定义卡片内容 // 修改迭代仪表盘自定义卡片内容 diff --git a/api_iteration_test.go b/api_iteration_test.go index c7abd8a..d834937 100644 --- a/api_iteration_test.go +++ b/api_iteration_test.go @@ -112,6 +112,61 @@ func TestIterationService_GetIterationsCount(t *testing.T) { assert.Equal(t, 106, count) } +func TestIterationService_UpdateIteration(t *testing.T) { + _, client := createServerClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, http.MethodPost, r.Method) + assert.Equal(t, "/iterations", r.URL.Path) + + var req struct { + WorkspaceID int `json:"workspace_id"` + Name string `json:"name"` + StartDate string `json:"startdate"` + EndDate string `json:"enddate"` + Creator string `json:"creator"` + Label string `json:"label"` + } + + require.NoError(t, json.NewDecoder(r.Body).Decode(&req)) + assert.Equal(t, 111, req.WorkspaceID) + assert.Equal(t, "测试迭代1", req.Name) + assert.Equal(t, "2025-01-01", req.StartDate) + assert.Equal(t, "2025-01-31", req.EndDate) + assert.Equal(t, "creator name", req.Creator) + assert.Equal(t, "label1|label2", req.Label) + + _, _ = w.Write(loadData(t, ".testdata/api/iteration/update_iteration.json")) + })) + + iteration, _, err := client.IterationService.UpdateIteration(ctx, &UpdateIterationRequest{ + WorkspaceID: Ptr(111), + ID: Ptr(11111222001002235), + CurrentUser: Ptr("current user"), + Name: Ptr("测试迭代1"), + StartDate: Ptr("2025-01-01"), + EndDate: Ptr("2025-01-31"), + Creator: Ptr("creator name"), + Label: NewEnum("label1", "label2"), + }) + assert.NoError(t, err) + require.NotNil(t, iteration) + + assert.Equal(t, "11111222001002235", iteration.ID) + assert.Equal(t, "2025 年 M1-迭代", iteration.Name) + assert.Equal(t, "111222", iteration.WorkspaceID) + assert.Equal(t, "2025-01-01", iteration.StartDate) + assert.Equal(t, "2025-01-31", iteration.EndDate) + assert.Equal(t, "open", iteration.Status) + assert.Equal(t, "creator name", iteration.Creator) + assert.Equal(t, "2024-12-27 17:04:43", iteration.Created) + assert.Equal(t, "2024-12-27 17:04:43", iteration.Modified) + assert.Equal(t, "iteration", iteration.EntityType) + assert.Equal(t, "0", iteration.ParentID) + assert.Equal(t, "11111222001002235", iteration.AncestorID) + assert.Equal(t, "11111222001002235:", iteration.Path) + assert.Equal(t, "11111222001000098", iteration.WorkitemTypeID) + assert.Equal(t, "11111222001000218", iteration.TemplatedID) +} + func TestIterationService_GetWorkitemTypes(t *testing.T) { _, client := createServerClient(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, http.MethodGet, r.Method)