diff --git a/README.md b/README.md index 9ca8383..9efb945 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Zentao API client enabling Go programs to interact with Zentao in a simple and u - [x] 创建产品 - [x] 产品计划(ProductsPlans) - [x] 创建计划 + - [x] 创建子计划 - [x] 获取产品计划列表 - [x] 获取计划详情 - [x] 修改计划 @@ -46,6 +47,7 @@ Zentao API client enabling Go programs to interact with Zentao in a simple and u - [x] 产品计划取消关联需求 - [x] 产品计划关联Bug - [x] 产品计划取消关联Bug + - [ ] 操作计划(开启、关闭、完成) - [x] 发布 - [x] 获取项目发布列表 - [x] 获取产品发布列表 diff --git a/example/productsplans/main.go b/example/productsplans/main.go index bec604b..c24f735 100644 --- a/example/productsplans/main.go +++ b/example/productsplans/main.go @@ -18,6 +18,7 @@ package main import ( "log" + "time" "github.com/easysoft/go-zentao/v20/zentao" @@ -34,22 +35,71 @@ func main() { zentao.WithoutProxy(), ) if err != nil { - log.Fatal(err) + panic(err) } - pds, _, err := zt.Products.List() + pds, _, err := zt.ProductPlans.List(1) if err != nil { - log.Fatal(err) + panic(err) } - log.Printf("Products count: %v", len(pds.Products)) - for _, pd := range pds.Products { - log.Printf("products id: %v", pd.ID) - pdps, _, err := zt.ProductPlans.List(pd.ID) - if err != nil { - panic(err) - } - for _, pdp := range pdps.Plans { - log.Printf("products plans id: %v", pdp.ID) - spew.Dump(pdp) - } + log.Printf("product 1 plan count: %v", len(pds.Plans)) + p1, _, err := zt.ProductPlans.Create(1, zentao.ProductPlanMeta{ + Title: "gosdk-" + time.Now().String(), + }) + if err != nil { + panic(err) + } + log.Printf("product 1 create productplan id: %v", p1.ID) + p2, _, err := zt.ProductPlans.GetByID(p1.ID) + if err != nil { + panic(err) + } + log.Printf("product 1 get productplan id: %v", p2.ID) + spew.Dump(p2) + p3, _, err := zt.ProductPlans.UpdateByID(p2.ID, zentao.ProductPlanMeta{ + Title: "gosdk-" + time.Now().String(), + }) + if err != nil { + panic(err) + } + log.Printf("product 1 update productplan id: %v", p3.ID) + spew.Dump(p3) + p4, _, err := zt.ProductPlans.LinkStories(p3.ID, zentao.PlansStoriesIDs{ + Stories: []int{1, 2, 3}, + }) + if err != nil { + panic(err) + } + log.Printf("product 1 link stories to productplan, stories: %v", len(p4.Stories)) + p5, _, err := zt.ProductPlans.UnLinkStories(p3.ID, zentao.PlansStoriesIDs{ + Stories: []int{1, 2}, + }) + if err != nil { + panic(err) + } + log.Printf("product 1 unlink stories to productplan, exist stories: %v", len(p5.Stories)) + p6, _, err := zt.ProductPlans.LinkBugs(p3.ID, zentao.PlansBugIDs{ + Bugs: []int{1, 2, 3}, + }) + if err != nil { + panic(err) + } + log.Printf("product 1 link bugs to productplan, bugs: %v", len(p6.Bugs)) + p7, _, err := zt.ProductPlans.UnLinkBugs(p3.ID, zentao.PlansBugIDs{ + Bugs: []int{1}, + }) + if err != nil { + panic(err) + } + log.Printf("product 1 link bugs to productplan, exist bugs: %v", len(p7.Bugs)) + p8, _, err := zt.ProductPlans.CreateSub(1, p3.ID, zentao.ProductPlanMeta{ + Title: "sub-gosdk-" + time.Now().String(), + }) + if err != nil { + panic(err) + } + log.Printf("product 1 create sub productplan id: %v", p8.ID) + _, _, err = zt.ProductPlans.DeleteByID(p8.ID) + if err != nil { + panic(err) } } diff --git a/zentao/bugs.go b/zentao/bugs.go index 583c5ef..0803808 100644 --- a/zentao/bugs.go +++ b/zentao/bugs.go @@ -18,7 +18,6 @@ package zentao import ( "fmt" - "time" "github.com/imroc/req/v3" ) @@ -52,52 +51,52 @@ type BugMeta struct { type BugBody struct { BugMeta - ID int `json:"id"` - Project int `json:"project"` - Product int `json:"product"` - Plan int `json:"plan"` - Storyversion int `json:"storyVersion"` - Totask int `json:"toTask"` - Tostory int `json:"toStory"` - Keywords string `json:"keywords"` - Hardware string `json:"hardware"` - Found string `json:"found"` - Status interface{} `json:"status,omitempty"` // 列表返回结构体, 详情返回字符串 - Substatus string `json:"subStatus"` - Color string `json:"color"` - Confirmed int `json:"confirmed"` - Activatedcount int `json:"activatedCount"` - Entry string `json:"entry"` - Lines string `json:"lines"` - V1 string `json:"v1"` - V2 string `json:"v2"` - Duplicatebug int `json:"duplicateBug"` - Linkbug string `json:"linkBug"` - Case int `json:"case"` - Caseversion int `json:"caseVersion"` - Result int `json:"result"` - Repo int `json:"repo"` - Repotype string `json:"repoType"` - Testtask int `json:"testtask"` - Deleted bool `json:"deleted"` - Activateddate time.Time `json:"activatedDate"` - Feedbackby string `json:"feedbackBy,omitempty"` // 仅bug接口 - Notifyemail string `json:"notifyEmail,omitempty"` // 仅bug接口 - Mailto []interface{} `json:"mailto"` - Openedby UserMeta `json:"openedBy"` - Openeddate time.Time `json:"openedDate"` - Openedbuild string `json:"openedBuild"` - Assignedto UserMeta `json:"assignedTo"` - Assigneddate time.Time `json:"assignedDate"` - Resolvedby interface{} `json:"resolvedBy"` - Resolution string `json:"resolution"` - Resolvedbuild string `json:"resolvedBuild"` - Resolveddate interface{} `json:"resolvedDate"` - Closedby interface{} `json:"closedBy"` - Closeddate time.Time `json:"closedDate"` - Lasteditedby UserMeta `json:"lastEditedBy"` - Lastediteddate time.Time `json:"lastEditedDate"` - Needconfirm bool `json:"needconfirm,omitempty"` // 仅列表返回 + ID int `json:"id"` + Project int `json:"project"` + Product int `json:"product"` + Plan int `json:"plan"` + Storyversion int `json:"storyVersion"` + Totask int `json:"toTask"` + Tostory int `json:"toStory"` + Keywords string `json:"keywords"` + Hardware string `json:"hardware"` + Found string `json:"found"` + Status any `json:"status,omitempty"` // 列表返回结构体, 详情返回字符串 + Substatus string `json:"subStatus"` + Color string `json:"color"` + Confirmed int `json:"confirmed"` + Activatedcount int `json:"activatedCount"` + Entry string `json:"entry"` + Lines string `json:"lines"` + V1 string `json:"v1"` + V2 string `json:"v2"` + Duplicatebug int `json:"duplicateBug"` + Linkbug string `json:"linkBug"` + Case int `json:"case"` + Caseversion int `json:"caseVersion"` + Result int `json:"result"` + Repo int `json:"repo"` + Repotype string `json:"repoType"` + Testtask int `json:"testtask"` + Deleted string `json:"deleted"` + Activateddate string `json:"activatedDate"` + Feedbackby string `json:"feedbackBy,omitempty"` // 仅bug接口 + Notifyemail string `json:"notifyEmail,omitempty"` // 仅bug接口 + Mailto any `json:"mailto"` + Openedby any `json:"openedBy"` + Openeddate string `json:"openedDate"` + Openedbuild string `json:"openedBuild"` + Assignedto any `json:"assignedTo"` + Assigneddate any `json:"assignedDate"` + Resolvedby any `json:"resolvedBy"` + Resolution string `json:"resolution"` + Resolvedbuild string `json:"resolvedBuild"` + Resolveddate any `json:"resolvedDate"` + Closedby any `json:"closedBy"` + Closeddate string `json:"closedDate"` + Lasteditedby any `json:"lastEditedBy"` + Lastediteddate string `json:"lastEditedDate"` + Needconfirm bool `json:"needconfirm,omitempty"` // 仅列表返回 } type BugCreateMeta struct { diff --git a/zentao/productplans.go b/zentao/productplans.go index 0b175dc..74eeb81 100644 --- a/zentao/productplans.go +++ b/zentao/productplans.go @@ -27,7 +27,7 @@ type ProductPlansService struct { } type ProductPlanMeta struct { - Branch int `json:"branch,omitempty"` + Branch any `json:"branch,omitempty"` // 创建时是int, List时是string Title string `json:"title"` Parent int `json:"parent,omitempty"` Desc string `json:"desc,omitempty"` @@ -54,14 +54,16 @@ type ProductPlanCreateMsg struct { type ProductPlanListBody struct { ProductPlanBody - Status string `json:"status,omitempty"` - ClosedReason string `json:"closedReason"` - Stories int `json:"stories"` - Bugs int `json:"bugs"` - Hour int `json:"hour"` - Project int `json:"project"` - ProjectID string `json:"projectID"` - Expired bool `json:"expired"` + BranchName string `json:"branchName,omitempty"` + Status string `json:"status,omitempty"` + ClosedReason string `json:"closedReason,omitempty"` + Stories int `json:"stories"` + Bugs int `json:"bugs"` + Hour int `json:"hour"` + Project int `json:"project"` + ProjectID string `json:"projectID"` + Expired bool `json:"expired"` + Actions []string `json:"actions,omitempty"` } type ProductPlanListMsg struct { @@ -73,8 +75,8 @@ type ProductPlanListMsg struct { type ProductPlanGetMsg struct { ProductPlanBody - Stories []StoriesBody `json:"stories"` - Bugs []BugBody `json:"bugs"` + Stories []StoriesBody `json:"stories,omitempty"` + Bugs []BugBody `json:"bugs,omitempty"` } type ProductPlanUpdateMsg struct { @@ -84,11 +86,11 @@ type ProductPlanUpdateMsg struct { } type PlansStoriesIDs struct { - Stories []string `json:"stories"` + Stories []int `json:"stories"` } type PlansBugIDs struct { - Bugs []string `json:"bugs"` + Bugs []int `json:"bugs"` } type LinkStoriesMsg struct { @@ -108,6 +110,18 @@ func (s *ProductPlansService) Create(id int, plan ProductPlanMeta) (*ProductPlan return &u, resp, err } +// CreateSub 创建产品子计划 +func (s *ProductPlansService) CreateSub(id, planID int, plan ProductPlanMeta) (*ProductPlanCreateMsg, *req.Response, error) { + var u ProductPlanCreateMsg + plan.Parent = planID + resp, err := s.client.client.R(). + SetHeader("Token", s.client.token). + SetBody(&plan). + SetSuccessResult(&u). + Post(s.client.RequestURL(fmt.Sprintf("/products/%d/plans", id))) + return &u, resp, err +} + // List 获取产品计划列表 func (s *ProductPlansService) List(id int) (*ProductPlanListMsg, *req.Response, error) { var u ProductPlanListMsg @@ -178,7 +192,7 @@ func (s *ProductPlansService) LinkBugs(id int, bug PlansBugIDs) (*LinkStoriesMsg SetHeader("Token", s.client.token). SetBody(&bug). SetSuccessResult(&u). - Post(s.client.RequestURL(fmt.Sprintf("/productplans/%d/linkBugs", id))) + Post(s.client.RequestURL(fmt.Sprintf("/productplans/%d/linkbugs", id))) return &u, resp, err } diff --git a/zentao/stories.go b/zentao/stories.go index d7386c9..bdef559 100644 --- a/zentao/stories.go +++ b/zentao/stories.go @@ -18,7 +18,6 @@ package zentao import ( "fmt" - "time" "github.com/imroc/req/v3" ) @@ -51,40 +50,40 @@ type StoriesExtMeta struct { type StoriesBody struct { StoriesExtMeta - ID int `json:"id"` - Parent int `json:"parent"` - Product int `json:"product"` - Branch int `json:"branch"` - Module int `json:"module"` - Plan string `json:"plan"` - Frombug int `json:"fromBug"` - Title string `json:"title"` - Type string `json:"type"` - Status string `json:"status"` - Substatus string `json:"subStatus"` - Color string `json:"color"` - Stage string `json:"stage"` - Stagedby string `json:"stagedBy"` - Mailto string `json:"mailto"` - Openedby UserMeta `json:"openedBy"` - Openeddate time.Time `json:"openedDate"` - Assignedto string `json:"assignedTo"` - Assigneddate interface{} `json:"assignedDate"` - Lasteditedby string `json:"lastEditedBy"` - Lastediteddate time.Time `json:"lastEditedDate"` - Reviewedby string `json:"reviewedBy"` - Revieweddate interface{} `json:"reviewedDate"` - Closedby string `json:"closedBy"` - Closeddate interface{} `json:"closedDate"` - Closedreason string `json:"closedReason"` - Tobug int `json:"toBug"` - Childstories string `json:"childStories"` - Linkstories string `json:"linkStories"` - Duplicatestory int `json:"duplicateStory"` - Version int `json:"version"` - Urchanged string `json:"URChanged"` - Deleted string `json:"deleted"` - Plantitle string `json:"planTitle,omitempty"` + ID int `json:"id"` + Parent any `json:"parent"` // 可能是数组, 产品计划时是数组 + Product int `json:"product"` + Branch int `json:"branch"` + Module int `json:"module"` + Plan string `json:"plan"` + Frombug int `json:"fromBug"` + Title string `json:"title"` + Type string `json:"type"` + Status string `json:"status"` + Substatus string `json:"subStatus"` + Color string `json:"color"` + Stage string `json:"stage"` + Stagedby string `json:"stagedBy"` + Mailto string `json:"mailto"` + Openedby any `json:"openedBy"` // 产品计划是string, 其他可能是UserMeta + Openeddate string `json:"openedDate"` + Assignedto string `json:"assignedTo"` + Assigneddate any `json:"assignedDate"` + Lasteditedby string `json:"lastEditedBy"` + Lastediteddate string `json:"lastEditedDate"` + Reviewedby string `json:"reviewedBy"` + Revieweddate any `json:"reviewedDate"` + Closedby string `json:"closedBy"` + Closeddate any `json:"closedDate"` + Closedreason string `json:"closedReason"` + Tobug int `json:"toBug"` + Childstories string `json:"childStories"` + Linkstories string `json:"linkStories"` + Duplicatestory int `json:"duplicateStory"` + Version int `json:"version"` + Urchanged string `json:"URChanged"` + Deleted string `json:"deleted"` + Plantitle string `json:"planTitle,omitempty"` } type StoriesCreateMeta struct {