From 0017147cbd714360862a095748d687b8ae6b5862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E8=BF=AA=E6=96=87?= <3117675914@qq.com> Date: Wed, 3 Jun 2026 09:14:57 +0800 Subject: [PATCH] feat: org +teams/+create-team/+remove-user, search +code/+issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - org +teams: 列出组织下的所有团队 - org +create-team: 在组织下创建新团队 - org +remove-user: 从组织中移除成员 - search +code: 在仓库中搜索代码 - search +issues: 搜索 Issue(支持状态/标签/作者过滤) Co-Authored-By: Claude Opus 4.8 --- shortcuts/org/org.go | 66 ++++++++++++++++++++++++++++++++++ shortcuts/search/search.go | 73 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/shortcuts/org/org.go b/shortcuts/org/org.go index f0b5e72..1003b6b 100644 --- a/shortcuts/org/org.go +++ b/shortcuts/org/org.go @@ -85,6 +85,72 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut { } return ctx.Output(env) }, + { + Name: "teams", + Description: "列出组织下的所有团队", + Flags: []common.Flag{ + {Name: "id", Usage: "组织 ID", Required: true}, + }, + Run: func(ctx *common.RuntimeContext) error { + id, err := ctx.RequireArg("id") + if err != nil { + return err + } + env, err := ctx.CallAPI("GET", fmt.Sprintf("/organizations/%s/teams", id), nil) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "create-team", + Description: "在组织下创建新团队", + Flags: []common.Flag{ + {Name: "id", Usage: "组织 ID", Required: true}, + {Name: "name", Short: "n", Usage: "团队名称", Required: true}, + }, + Run: func(ctx *common.RuntimeContext) error { + id, err := ctx.RequireArg("id") + if err != nil { + return err + } + name, err := ctx.RequireArg("name") + if err != nil { + return err + } + body := map[string]interface{}{"name": name} + env, err := ctx.CallAPI("POST", fmt.Sprintf("/organizations/%s/teams", id), body) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "remove-user", + Description: "从组织中移除成员", + Flags: []common.Flag{ + {Name: "id", Usage: "组织 ID", Required: true}, + {Name: "user", Short: "u", Usage: "要移除的用户 ID", Required: true}, + }, + Run: func(ctx *common.RuntimeContext) error { + orgID, err := ctx.RequireArg("id") + if err != nil { + return err + } + userID, err := ctx.RequireArg("user") + if err != nil { + return err + } + path := fmt.Sprintf("/organizations/%s/organization_users/%s", orgID, userID) + env, err := ctx.CallAPI("DELETE", path, nil) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, }, } } diff --git a/shortcuts/search/search.go b/shortcuts/search/search.go index a0ee4c2..ab81f91 100644 --- a/shortcuts/search/search.go +++ b/shortcuts/search/search.go @@ -1,6 +1,7 @@ package search import ( + "fmt" "net/url" "github.com/gitlink-org/gitlink-cli/internal/i18n" @@ -51,6 +52,78 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut { } return ctx.Output(env) }, + { + Name: "code", + Description: "在仓库中搜索代码", + Flags: []common.Flag{ + {Name: "keyword", Short: "k", Usage: "搜索关键词", Required: true}, + {Name: "owner", Usage: "仓库所有者(可选,限定范围)"}, + {Name: "repo", Usage: "仓库名称(可选,限定范围)"}, + {Name: "language", Usage: "编程语言过滤(如 go, python)"}, + {Name: "page", Short: "p", Usage: "页码", Default: "1"}, + {Name: "limit", Short: "l", Usage: "每页数量", Default: "20"}, + }, + Run: func(ctx *common.RuntimeContext) error { + keyword, err := ctx.RequireArg("keyword") + if err != nil { + return err + } + q := url.Values{} + q.Set("keyword", keyword) + q.Set("page", ctx.Arg("page")) + q.Set("limit", ctx.Arg("limit")) + if lang := ctx.Arg("language"); lang != "" { + q.Set("language", lang) + } + path := "/search/code" + if owner := ctx.Arg("owner"); owner != "" { + if repo := ctx.Arg("repo"); repo != "" { + path = fmt.Sprintf("/%s/%s/search/code", owner, repo) + } + } + env, err := ctx.CallAPIWithQuery("GET", path, q) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, + { + Name: "issues", + Description: "搜索 Issue", + Flags: []common.Flag{ + {Name: "keyword", Short: "k", Usage: "搜索关键词", Required: true}, + {Name: "state", Short: "s", Usage: "状态过滤: open/closed/all", Default: "all"}, + {Name: "label", Usage: "标签过滤"}, + {Name: "author", Usage: "作者过滤"}, + {Name: "page", Short: "p", Usage: "页码", Default: "1"}, + {Name: "limit", Short: "l", Usage: "每页数量", Default: "20"}, + }, + Run: func(ctx *common.RuntimeContext) error { + keyword, err := ctx.RequireArg("keyword") + if err != nil { + return err + } + q := url.Values{} + q.Set("keyword", keyword) + q.Set("page", ctx.Arg("page")) + q.Set("limit", ctx.Arg("limit")) + if state := ctx.Arg("state"); state != "" && state != "all" { + q.Set("state", state) + } + if label := ctx.Arg("label"); label != "" { + q.Set("label", label) + } + if author := ctx.Arg("author"); author != "" { + q.Set("author", author) + } + env, err := ctx.CallAPIWithQuery("GET", "/search/issues", q) + if err != nil { + return err + } + return ctx.Output(env) + }, + }, }, } } -- 2.34.1