gitlink-cli/shortcuts/user/user.go

816 lines
22 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package user
import (
"encoding/json"
"fmt"
"net/url"
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
)
func Shortcuts() []*common.Shortcut {
return []*common.Shortcut{
// +me显示当前登录用户信息
{
Name: "me",
Description: "显示当前登录用户",
Long: `Show profile information for the currently authenticated user.
Displays login name, email, and account details based on the
configured API token.`,
Example: ` # Show current user profile
gitlink user +me`,
Run: func(ctx *common.RuntimeContext) error {
env, err := ctx.CallAPI("GET", "/users/me", nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +info显示指定用户的资料
{
Name: "info",
Description: "显示用户资料",
Long: `Show public profile information for a GitLink user.
Looks up the user by their login name and displays their
username, bio, and other public profile fields.`,
Example: ` # Show profile for a specific user
gitlink user +info --login zhangsan`,
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Message management ---
// +messages列出用户的私信
{
Name: "messages",
Description: "列出用户私信",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "page", Usage: "Page number", Default: "1"},
{Name: "limit", Usage: "Items per page", Default: "20"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
page := ctx.Arg("page")
if page == "" {
page = "1"
}
limit := ctx.Arg("limit")
if limit == "" {
limit = "20"
}
query := url.Values{}
query.Set("page", page)
query.Set("limit", limit)
env, err := ctx.CallAPIWithQuery("GET", fmt.Sprintf("/users/%s/messages", login), query)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +delete-message删除一条私信
{
Name: "delete-message",
Description: "删除一条私信",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Message ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
query := url.Values{}
query.Set("id", id)
env, err := ctx.CallAPIWithQuery("DELETE", fmt.Sprintf("/users/%s/messages", login), query)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +create-message发送一条私信
{
Name: "create-message",
Description: "发送一条私信",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "content", Usage: "Message content", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
content, err := ctx.RequireArg("content")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/messages", login), map[string]interface{}{
"content": content,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +read-message将私信标记为已读
{
Name: "read-message",
Description: "将私信标记为已读",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Message ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/messages/read", login), map[string]interface{}{
"id": id,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +msg-settings获取消息通知设置
{
Name: "msg-settings",
Description: "获取消息通知设置",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/template_message_settings", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +update-msg-settings更新消息通知设置
{
Name: "update-msg-settings",
Description: "更新消息通知设置",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "settings", Usage: "Settings JSON array", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
settingsStr, err := ctx.RequireArg("settings")
if err != nil {
return err
}
var settings []interface{}
if err := json.Unmarshal([]byte(settingsStr), &settings); err != nil {
return fmt.Errorf("invalid settings JSON: %w", err)
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/template_message_settings/update_setting", login), map[string]interface{}{
"setting": settings,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Pinned projects ---
// +pinned-projects列出置顶项目
{
Name: "pinned-projects",
Description: "列出置顶项目",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/is_pinned_projects", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +pin-project置顶一个项目
{
Name: "pin-project",
Description: "置顶一个项目",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Project ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/is_pinned_projects/pin", login), map[string]interface{}{
"id": id,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +reorder-pinned调整置顶项目的顺序
{
Name: "reorder-pinned",
Description: "调整置顶项目的顺序",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Pinned project ID", Required: true},
{Name: "position", Usage: "New position", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
position, err := ctx.RequireArg("position")
if err != nil {
return err
}
env, err := ctx.CallAPI("PUT", fmt.Sprintf("/users/%s/is_pinned_projects/%s", login, id), map[string]interface{}{
"position": position,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Statistics ---
// +activity获取用户活动统计
{
Name: "activity",
Description: "获取用户活动统计",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/activity", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +headmap获取用户活跃热力图数据
{
Name: "headmap",
Description: "获取用户活跃热力图数据",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/headmaps", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +develop-stats获取用户开发统计
{
Name: "develop-stats",
Description: "获取用户开发统计",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/develop", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +role-stats获取用户角色统计
{
Name: "role-stats",
Description: "获取用户角色统计",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/role", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +major-stats获取用户专业统计
{
Name: "major-stats",
Description: "获取用户专业统计",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/statistics/major", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Transfer / Apply ---
// +applied-transfers列出待处理的仓库转让申请
{
Name: "applied-transfers",
Description: "列出待处理的仓库转让申请",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/applied_transfer_projects", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +accept-transfer接受仓库转让申请
{
Name: "accept-transfer",
Description: "接受仓库转让申请",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Transfer ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_transfer_projects/%s/accept", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +refuse-transfer拒绝仓库转让申请
{
Name: "refuse-transfer",
Description: "拒绝仓库转让申请",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Transfer ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_transfer_projects/%s/refuse", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +applied-projects列出待处理的仓库加入申请
{
Name: "applied-projects",
Description: "列出待处理的仓库加入申请",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("GET", fmt.Sprintf("/users/%s/applied_projects", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +accept-join接受仓库加入申请
{
Name: "accept-join",
Description: "接受仓库加入申请",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Application ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_projects/%s/accept", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +refuse-join拒绝仓库加入申请
{
Name: "refuse-join",
Description: "拒绝仓库加入申请",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "id", Usage: "Application ID", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
id, err := ctx.RequireArg("id")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/users/%s/applied_projects/%s/refuse", login, id), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Feedback / Update ---
// +feedback提交反馈意见
{
Name: "feedback",
Description: "提交反馈意见",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "content", Usage: "Feedback content", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
content, err := ctx.RequireArg("content")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/feedbacks", login), map[string]interface{}{
"content": content,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +update更新用户资料
{
Name: "update",
Description: "更新用户资料",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "nickname", Usage: "New nickname"},
{Name: "description", Usage: "New description"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
body := map[string]interface{}{}
if v := ctx.Arg("nickname"); v != "" {
body["nickname"] = v
}
if v := ctx.Arg("description"); v != "" {
body["description"] = v
}
env, err := ctx.CallAPI("PUT", fmt.Sprintf("/users/%s", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// --- Account settings ---
// +change-password修改账户密码
{
Name: "change-password",
Description: "修改账户密码",
Flags: []common.Flag{
{Name: "old-password", Usage: "Current password", Required: true},
{Name: "new-password", Usage: "New password", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
oldPwd, err := ctx.RequireArg("old-password")
if err != nil {
return err
}
newPwd, err := ctx.RequireArg("new-password")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", "/accounts/change_password", map[string]interface{}{
"old_password": oldPwd,
"new_password": newPwd,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +update-email更新邮箱地址
{
Name: "update-email",
Description: "更新邮箱地址",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "email", Usage: "New email address", Required: true},
{Name: "code", Usage: "Verification code"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
email, err := ctx.RequireArg("email")
if err != nil {
return err
}
body := map[string]interface{}{
"email": email,
}
if v := ctx.Arg("code"); v != "" {
body["code"] = v
}
env, err := ctx.CallAPI("PATCH", fmt.Sprintf("/v1/%s/update_email", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +update-phone更新手机号码
{
Name: "update-phone",
Description: "更新手机号码",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "phone", Usage: "New phone number", Required: true},
{Name: "code", Usage: "Verification code"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
phone, err := ctx.RequireArg("phone")
if err != nil {
return err
}
body := map[string]interface{}{
"phone": phone,
}
if v := ctx.Arg("code"); v != "" {
body["code"] = v
}
env, err := ctx.CallAPI("PATCH", fmt.Sprintf("/v1/%s/update_phone", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +send-verify发送邮箱验证码
{
Name: "send-verify",
Description: "发送邮箱验证码",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "email", Usage: "Email address"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
query := url.Values{}
if v := ctx.Arg("email"); v != "" {
query.Set("email", v)
}
env, err := ctx.CallAPIWithQuery("GET", fmt.Sprintf("/v1/%s/send_email_vefify_code", login), query)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +check-verify校验邮箱验证码
{
Name: "check-verify",
Description: "校验邮箱验证码",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "code", Usage: "Verification code", Required: true},
{Name: "email", Usage: "Email address"},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
code, err := ctx.RequireArg("code")
if err != nil {
return err
}
body := map[string]interface{}{
"code": code,
}
if v := ctx.Arg("email"); v != "" {
body["email"] = v
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_email_verify_code", login), body)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +check-password校验密码
{
Name: "check-password",
Description: "校验密码",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "password", Usage: "Password to verify", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
password, err := ctx.RequireArg("password")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_password", login), map[string]interface{}{
"password": password,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +check-email校验邮箱
{
Name: "check-email",
Description: "校验邮箱",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
{Name: "email", Usage: "Email to verify", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
email, err := ctx.RequireArg("email")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_email", login), map[string]interface{}{
"email": email,
})
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +can-delete检查账户是否可被注销
{
Name: "can-delete",
Description: "检查账户是否可被注销",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("POST", fmt.Sprintf("/v1/%s/check_user_can_delete", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
// +delete注销停用用户账户
{
Name: "delete",
Description: "注销(停用)用户账户",
Flags: []common.Flag{
{Name: "login", Short: "l", Usage: "User login name", Required: true},
},
Run: func(ctx *common.RuntimeContext) error {
login, err := ctx.RequireArg("login")
if err != nil {
return err
}
env, err := ctx.CallAPI("DELETE", fmt.Sprintf("/v1/%s", login), nil)
if err != nil {
return err
}
return ctx.Output(env)
},
},
}
}