| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- package plane_v1
- import (
- "encoding/json"
- "fmt"
- "go.uber.org/zap"
- )
- // ==================== Intake Issue 请求/响应结构 ====================
- // IntakeIssueRequest Intake Issue创建请求体
- type IntakeIssueRequest struct {
- Issue IntakeIssue `json:"issue"`
- Source string `json:"source"`
- }
- // IntakeIssue Issue详情
- type IntakeIssue struct {
- Name string `json:"name"`
- DescriptionHTML string `json:"description_html"`
- Priority string `json:"priority"`
- LabelIds []string `json:"label_ids,omitempty"`
- }
- // IntakeIssueResponse Intake Issue创建响应
- type IntakeIssueResponse struct {
- Id string `json:"id"`
- IssueId string `json:"issue"`
- Status int `json:"status"`
- Source string `json:"source"`
- CreatedAt string `json:"created_at"`
- }
- // IntakeListResponse Intake列表响应
- type IntakeListResponse struct {
- Results []IntakeListItem `json:"results"`
- TotalCount int `json:"total_count"`
- NextCursor string `json:"next_cursor"`
- }
- // IntakeListItem Intake列表项
- type IntakeListItem struct {
- Id string `json:"id"`
- Status int `json:"status"`
- Source string `json:"source"`
- CreatedAt string `json:"created_at"`
- Issue IntakeIssueInfo `json:"issue_detail"`
- }
- // IntakeIssueInfo Issue基础信息
- type IntakeIssueInfo struct {
- Id string `json:"id"`
- Name string `json:"name"`
- Priority string `json:"priority"`
- }
- // ==================== Intake Issue API操作 ====================
- // CreateIntakeIssue 创建Intake Issue
- func CreateIntakeIssue(req IntakeIssueRequest) (*IntakeIssueResponse, error) {
- url := fmt.Sprintf("/api/v1/workspaces/%s/projects/%s/intake-issues/",
- planeWorkspaceSlug,
- planeProjectId,
- )
- resp, err := planeHttpPost(url, req)
- if err != nil {
- zap.L().Error("[Plane] CreateIntakeIssue 请求失败", zap.String("err", err.Error()))
- return nil, fmt.Errorf("提交失败: %w", err)
- }
- if !isSuccess(resp.StatusCode) {
- zap.L().Error("[Plane] CreateIntakeIssue 返回错误",
- zap.String("status", resp.Status),
- zap.String("body", string(resp.Body)),
- )
- return nil, fmt.Errorf("提交失败: Plane 返回 %s", resp.Status)
- }
- var result IntakeIssueResponse
- if err := json.Unmarshal(resp.Body, &result); err != nil {
- zap.L().Error("[Plane] CreateIntakeIssue 响应解析失败", zap.String("err", err.Error()))
- return nil, fmt.Errorf("响应解析失败: %w", err)
- }
- zap.L().Info("[Plane] CreateIntakeIssue 成功", zap.String("id", result.Id))
- return &result, nil
- }
- // GetIntakeIssueList 查询Intake Issue列表
- func GetIntakeIssueList() (*IntakeListResponse, error) {
- url := fmt.Sprintf("/api/v1/workspaces/%s/projects/%s/intake-issues/?per_page=100&expand=issue_detail",
- planeWorkspaceSlug,
- planeProjectId,
- )
- resp, err := planeHttpGet(url)
- if err != nil {
- zap.L().Error("[Plane] GetIntakeIssueList 请求失败", zap.String("err", err.Error()))
- return nil, fmt.Errorf("查询失败: %w", err)
- }
- if !isSuccess(resp.StatusCode) {
- zap.L().Error("[Plane] GetIntakeIssueList 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("查询失败: Plane 返回 %s", resp.Status)
- }
- var listResp IntakeListResponse
- if err := json.Unmarshal(resp.Body, &listResp); err != nil {
- zap.L().Error("[Plane] GetIntakeIssueList 响应解析失败", zap.String("err", err.Error()))
- return nil, fmt.Errorf("响应解析失败: %w", err)
- }
- zap.L().Debug("[Plane] GetIntakeIssueList", zap.Int("count", len(listResp.Results)))
- return &listResp, nil
- }
- // GetIntakeIssueDetail 获取收件箱工作项详情
- func GetIntakeIssueDetail(issueID string) ([]byte, error) {
- url := fmt.Sprintf("/api/v1/workspaces/%s/projects/%s/intake-issues/%s/",
- planeWorkspaceSlug, planeProjectId, issueID)
- resp, err := planeHttpGet(url)
- if err != nil {
- zap.L().Error("[Plane] GetIntakeIssueDetail 请求失败", zap.Error(err))
- return nil, err
- }
- if !isSuccess(resp.StatusCode) {
- zap.L().Error("[Plane] GetIntakeIssueDetail 返回错误", zap.String("status", resp.Status))
- return nil, fmt.Errorf("GetIntakeIssueDetail 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // UpdateIntakeIssue 更新收件箱工作项
- func UpdateIntakeIssue(issueID string, data map[string]interface{}) ([]byte, error) {
- url := fmt.Sprintf("/api/v1/workspaces/%s/projects/%s/intake-issues/%s/",
- planeWorkspaceSlug, planeProjectId, issueID)
- resp, err := planeHttpPatch(url, data)
- if err != nil {
- zap.L().Error("[Plane] UpdateIntakeIssue 请求失败", zap.Error(err))
- return nil, err
- }
- if !isSuccess(resp.StatusCode) {
- zap.L().Error("[Plane] UpdateIntakeIssue 返回错误",
- zap.String("status", resp.Status),
- zap.String("body", string(resp.Body)),
- )
- return nil, fmt.Errorf("UpdateIntakeIssue 失败: %s", resp.Status)
- }
- return resp.Body, nil
- }
- // AcceptIntakeIssue 接受收件箱工作项
- func AcceptIntakeIssue(issueID string) ([]byte, error) {
- return UpdateIntakeIssue(issueID, map[string]interface{}{"status": 1})
- }
- // RejectIntakeIssue 拒绝收件箱工作项
- func RejectIntakeIssue(issueID string) ([]byte, error) {
- return UpdateIntakeIssue(issueID, map[string]interface{}{"status": -1})
- }
- // DeleteIntakeIssue 删除收件箱工作项
- func DeleteIntakeIssue(issueID string) error {
- url := fmt.Sprintf("/api/v1/workspaces/%s/projects/%s/intake-issues/%s/",
- planeWorkspaceSlug, planeProjectId, issueID)
- resp, err := planeHttpDelete(url)
- if err != nil {
- zap.L().Error("[Plane] DeleteIntakeIssue 请求失败", zap.Error(err))
- return err
- }
- if resp.StatusCode != 204 {
- zap.L().Error("[Plane] DeleteIntakeIssue 返回错误", zap.String("status", resp.Status))
- return fmt.Errorf("DeleteIntakeIssue 失败: %s", resp.Status)
- }
- return nil
- }
|