# 管理工作区成员

使用 AI Studio SDK 邀请成员并更新其角色。邀请返回的成员 ID 是读取成员详情和后续调整角色的交接信息。

(sdk-ai-studio-workspace-member-flow)=
## 任务流程

先选择目标工作区，再用一种联系标识邀请成员。邮箱和手机邀请在对方接受前保持待处理状态；使用 GitHub 登录名时，目录中已有的用户会返回成员 ID，未匹配的用户会返回空 ID，直到该用户首次登录。

获得成员 ID 后，才能读取成员详情、更新角色、更新状态或移除成员。更新角色的请求没有返回成员详情，因此需要再次读取确认。

(sdk-ai-studio-workspace-member-prepare)=
## 准备

| 需要的内容 | 如何取得 | 在本页中的作用 |
| --- | --- | --- |
| 已认证的客户端 | 在首次接入流程中创建。 | 访问工作区资源。 |
| 工作区 ID | 从工作区创建、列表或操作者选择中取得。 | 确定成员操作的范围。 |
| 成员姓名和一种联系标识 | 由管理员提供。 | 邀请成员。 |
| 已分配的角色和默认角色 | 由管理员按访问要求选择。 | 确定邀请或角色更新的访问范围。 |

(sdk-ai-studio-workspace-member-invite)=
## 邀请成员

下面的示例邀请一个邮箱成员，并保存返回的成员 ID。邮箱、手机号码和 GitHub 登录名三者只能提供其中一种；角色集合必须包含默认角色。

:::::{tab-set}
:sync-group: sdk-language

::::{tab-item} Python
:sync: python

```python
import os

import moi_product_sdk as sdk

client = sdk.new_with_personal_access_token(
    os.environ["PRODUCT_API_BASE_URL"],
    os.environ["PRODUCT_API_KEY"],
)
workspace = client.workspace("<workspace-id>")
default_role_id = 1
invitation = workspace.invite_member(
    "<member-name>",
    default_role_id,
    sdk.with_user_email("<member-email>"),
    sdk.with_user_role_ids(default_role_id),
)
member_id = invitation.id
print(member_id)
```

::::

::::{tab-item} Go
:sync: go

```go
package main

import (
	"context"
	"fmt"
	"os"

	sdk "github.com/matrixorigin/matrixflow/sdk/go-sdk"
)

func main() {
	ctx := context.Background()
	client, err := sdk.NewWithPersonalAccessToken(
		os.Getenv("PRODUCT_API_BASE_URL"),
		os.Getenv("PRODUCT_API_KEY"),
	)
	if err != nil {
		panic(err)
	}
	workspace, err := client.Workspace("<workspace-id>")
	if err != nil {
		panic(err)
	}
	const defaultRoleID = 1
	invitation, err := workspace.InviteMember(
		ctx,
		"<member-name>",
		defaultRoleID,
		sdk.WithUserEmail("<member-email>"),
		sdk.WithUserRoleIDs(defaultRoleID),
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(invitation.GetId())
}
```

::::

:::::

空成员 ID 表示还不能继续执行成员更新操作。请等待对应用户完成登录或接受邀请，再从成员列表或详情中取得可用 ID。

(sdk-ai-studio-workspace-member-confirm)=
## 确认成员角色

使用上一步取得的成员 ID 更新角色后，读取成员详情确认结果。角色更新只代表请求返回；后续需要依赖访问范围时，应以重新读取到的成员信息为准。

:::::{tab-set}
:sync-group: sdk-language

::::{tab-item} Python
:sync: python

```python
member = workspace.member(member_id)
role_id = 1
member.set_roles([role_id], role_id)
member_info = member.info()
print(member_info)
```

::::

::::{tab-item} Go
:sync: go

```go
member, err := workspace.Member(memberID)
if err != nil {
	panic(err)
}
roleID := 1
if err := member.SetRoles(ctx, []int{roleID}, roleID); err != nil {
	panic(err)
}
memberInfo, err := member.Info(ctx)
if err != nil {
	panic(err)
}
_ = memberInfo
```

::::

:::::

(sdk-ai-studio-workspace-member-current-role)=
## 选择 Go 客户端的当前角色

Go 客户端可在创建时为指定工作区配置当前角色。角色 ID 必须是没有前导零的正十进制整数；该配置只作用于对应工作区的请求。Python 当前没有相同的客户端配置入口。

```go
client, err := sdk.NewWithPersonalAccessToken(
	os.Getenv("PRODUCT_API_BASE_URL"),
	os.Getenv("PRODUCT_API_KEY"),
	sdk.WithWorkspaceCurrentRoleID("<workspace-id>", "<role-id>"),
)
if err != nil {
	panic(err)
}
_ = client
```

(sdk-ai-studio-workspace-member-next)=
## 下一步

- [管理卷和文件](catalog-tables-volumes-files.md)
- [运行并跟踪工作流](workflow-runtime.md)
