diff --git a/shortcuts/base/base_execute_test.go b/shortcuts/base/base_execute_test.go index cb619f740..3ae630103 100644 --- a/shortcuts/base/base_execute_test.go +++ b/shortcuts/base/base_execute_test.go @@ -584,17 +584,25 @@ func TestBaseTableExecuteUpdate(t *testing.T) { func TestBaseRecordExecuteUpsertUpdate(t *testing.T) { factory, stdout, reg := newExecuteFactory(t) - reg.Register(&httpmock.Stub{ + updateStub := &httpmock.Stub{ Method: "PATCH", URL: "/open-apis/base/v3/bases/app_x/tables/tbl_x/records/rec_x", Body: map[string]interface{}{ "code": 0, "data": map[string]interface{}{"record_id": "rec_x", "fields": map[string]interface{}{"Name": "Alice"}}, }, - }) - if err := runShortcut(t, BaseRecordUpsert, []string{"+record-upsert", "--base-token", "app_x", "--table-id", "tbl_x", "--record-id", "rec_x", "--json", `{"fields":{"Name":"Alice"}}`}, factory, stdout); err != nil { + } + reg.Register(updateStub) + if err := runShortcut(t, BaseRecordUpsert, []string{"+record-upsert", "--base-token", "app_x", "--table-id", "tbl_x", "--record-id", "rec_x", "--json", `{"Name":"Alice"}`}, factory, stdout); err != nil { t.Fatalf("err=%v", err) } + body := decodeCapturedJSONBody(t, updateStub) + if body["Name"] != "Alice" { + t.Fatalf("request body=%v", body) + } + if _, ok := body["fields"]; ok { + t.Fatalf("request body must not contain fields wrapper: %v", body) + } if got := stdout.String(); !strings.Contains(got, `"updated": true`) || !strings.Contains(got, `"rec_x"`) { t.Fatalf("stdout=%s", got) } @@ -1018,17 +1026,25 @@ func TestBaseRecordExecuteReadCreateDelete(t *testing.T) { t.Run("create", func(t *testing.T) { factory, stdout, reg := newExecuteFactory(t) - reg.Register(&httpmock.Stub{ + createStub := &httpmock.Stub{ Method: "POST", URL: "/open-apis/base/v3/bases/app_x/tables/tbl_x/records", Body: map[string]interface{}{ "code": 0, "data": map[string]interface{}{"record_id": "rec_new", "fields": map[string]interface{}{"Name": "Alice"}}, }, - }) - if err := runShortcut(t, BaseRecordUpsert, []string{"+record-upsert", "--base-token", "app_x", "--table-id", "tbl_x", "--json", `{"fields":{"Name":"Alice"}}`}, factory, stdout); err != nil { + } + reg.Register(createStub) + if err := runShortcut(t, BaseRecordUpsert, []string{"+record-upsert", "--base-token", "app_x", "--table-id", "tbl_x", "--json", `{"Name":"Alice"}`}, factory, stdout); err != nil { t.Fatalf("err=%v", err) } + body := decodeCapturedJSONBody(t, createStub) + if body["Name"] != "Alice" { + t.Fatalf("request body=%v", body) + } + if _, ok := body["fields"]; ok { + t.Fatalf("request body must not contain fields wrapper: %v", body) + } if got := stdout.String(); !strings.Contains(got, `"created": true`) || !strings.Contains(got, `"rec_new"`) { t.Fatalf("stdout=%s", got) } diff --git a/shortcuts/base/base_shortcuts_test.go b/shortcuts/base/base_shortcuts_test.go index b48aec1eb..088a536eb 100644 --- a/shortcuts/base/base_shortcuts_test.go +++ b/shortcuts/base/base_shortcuts_test.go @@ -252,6 +252,7 @@ func TestBaseTableValidate(t *testing.T) { } func TestBaseRecordValidate(t *testing.T) { + ctx := context.Background() if BaseRecordList.Validate != nil { t.Fatalf("record list validate should be nil for repeatable --field-id") } @@ -264,6 +265,9 @@ func TestBaseRecordValidate(t *testing.T) { if BaseRecordUpsert.Validate == nil { t.Fatalf("record upsert validate should reject invalid JSON before dry-run") } + if err := BaseRecordUpsert.Validate(ctx, newBaseTestRuntime(map[string]string{"base-token": "b", "table-id": "tbl_1", "json": `{"Name":"Alice"}`}, nil, nil)); err != nil { + t.Fatalf("record upsert map validate err=%v", err) + } } func TestBaseViewValidate(t *testing.T) { diff --git a/shortcuts/base/helpers.go b/shortcuts/base/helpers.go index 0c5639e0a..a456183c6 100644 --- a/shortcuts/base/helpers.go +++ b/shortcuts/base/helpers.go @@ -572,30 +572,6 @@ func resolveViewRef(views []map[string]interface{}, ref string) (map[string]inte return nil, fmt.Errorf("view %q not found", ref) } -func normalizeRecordInputs(raw string) ([]map[string]interface{}, error) { - var records []interface{} - if err := common.ParseJSON([]byte(raw), &records); err != nil { - return nil, fmt.Errorf("--records invalid JSON, must be a record array") - } - result := make([]map[string]interface{}, 0, len(records)) - for idx, item := range records { - record, ok := item.(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("record %d must be an object", idx+1) - } - if fields, ok := record["fields"].(map[string]interface{}); ok { - normalized := map[string]interface{}{"fields": fields} - if recordID, ok := record["record_id"].(string); ok && recordID != "" { - normalized["record_id"] = recordID - } - result = append(result, normalized) - continue - } - result = append(result, map[string]interface{}{"fields": record}) - } - return result, nil -} - func chunkRecords(records []map[string]interface{}, size int) [][]map[string]interface{} { if size <= 0 { size = 1 diff --git a/shortcuts/base/helpers_test.go b/shortcuts/base/helpers_test.go index 587d14671..fc54b5d54 100644 --- a/shortcuts/base/helpers_test.go +++ b/shortcuts/base/helpers_test.go @@ -189,13 +189,7 @@ func TestBaseV3Helpers(t *testing.T) { } func TestRecordAndChunkHelpers(t *testing.T) { - records, err := normalizeRecordInputs(`[{"record_id":"rec_1","fields":{"Name":"Alice"}},{"Name":"Bob"}]`) - if err != nil || len(records) != 2 { - t.Fatalf("records=%v err=%v", records, err) - } - if _, err := normalizeRecordInputs(`[1]`); err == nil || !strings.Contains(err.Error(), "must be an object") { - t.Fatalf("err=%v", err) - } + records := []map[string]interface{}{{"record_id": "rec_1"}, {"record_id": "rec_2"}} if len(chunkRecords(records, 1)) != 2 || len(chunkStringIDs([]string{"a", "b", "c"}, 2)) != 2 { t.Fatalf("chunk helpers mismatch") } diff --git a/shortcuts/base/record_batch_create.go b/shortcuts/base/record_batch_create.go index 480bcd50c..5e0d85c36 100644 --- a/shortcuts/base/record_batch_create.go +++ b/shortcuts/base/record_batch_create.go @@ -24,6 +24,7 @@ var BaseRecordBatchCreate = common.Shortcut{ Tips: []string{ `Example: --json '{"fields":["Title","Status"],"rows":[["Task A","Open"],["Task B","Done"]]}'`, "Agent hint: use the lark-base skill's record-batch-create guide for usage and limits.", + "Agent hint: use lark-base-cell-value.md as the source of truth for each CellValue.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateRecordJSON(runtime) diff --git a/shortcuts/base/record_batch_update.go b/shortcuts/base/record_batch_update.go index deefa4d18..4b8d026ae 100644 --- a/shortcuts/base/record_batch_update.go +++ b/shortcuts/base/record_batch_update.go @@ -24,6 +24,7 @@ var BaseRecordBatchUpdate = common.Shortcut{ Tips: []string{ `Example: --json '{"record_id_list":["recXXX"],"patch":{"Status":"Done"}}'`, "Agent hint: use the lark-base skill's record-batch-update guide for usage and limits.", + "Agent hint: use lark-base-cell-value.md as the source of truth for each patch CellValue.", }, Validate: func(ctx context.Context, runtime *common.RuntimeContext) error { return validateRecordJSON(runtime) diff --git a/shortcuts/base/record_upsert.go b/shortcuts/base/record_upsert.go index 13045a4d6..f83f8b8eb 100644 --- a/shortcuts/base/record_upsert.go +++ b/shortcuts/base/record_upsert.go @@ -20,7 +20,7 @@ var BaseRecordUpsert = common.Shortcut{ baseTokenFlag(true), tableRefFlag(true), recordRefFlag(false), - {Name: "json", Desc: "record JSON object", Required: true}, + {Name: "json", Desc: "record JSON object: Map", Required: true}, }, Tips: []string{ `Example: --json '{"Name":"Alice"}'`, diff --git a/skill-template/domains/base.md b/skill-template/domains/base.md index f3f3fffab..17b54c793 100644 --- a/skill-template/domains/base.md +++ b/skill-template/domains/base.md @@ -7,10 +7,10 @@ - `lark-cli base table.records create` ✅ - `lark-cli base records create` ❌ 2. **优先使用 Shortcut** — 有 Shortcut 的操作不要手拼原生 API -3. **写记录前** — 先调用 `table.fields list` 获取字段 `type/ui_type`,再读 [lark-base-shortcut-record-value.md](../../skills/lark-base/references/lark-base-shortcut-record-value.md) 确认每个字段类型的值格式 +3. **写记录前** — 先调用 `table.fields list` 获取字段 `type/ui_type`,再读 [lark-base-cell-value.md](../../skills/lark-base/references/lark-base-cell-value.md);该文档是 CellValue 的 source of truth 4. **写字段前** — 先读 [lark-base-shortcut-field-properties.md](../../skills/lark-base/references/lark-base-shortcut-field-properties.md) 确认字段类型的 `property` 结构 5. **筛选查询前** — 先读 [lark-base-view-set-filter.md](../../skills/lark-base/references/lark-base-view-set-filter.md),当前 `base/v3` 通过 `view.filter update + table.records list` 组合完成筛选读取 -6. **批量上限 500 条/次** — 同一表建议串行写入,并在批次间延迟 0.5–1 秒 +6. **批量上限 200 条/次** — 同一表建议串行写入,并在批次间延迟 0.5–1 秒 7. **改名和删除按明确意图执行** — 视图重命名这类低风险改名操作,目标和新名称明确时可直接执行;删除记录 / 字段 / 表时,只要用户已经明确要求删除且目标明确,也可直接执行,不需要再补一次确认 8. **不要走旧 bitable 路径** — Base 场景不要调用 `lark-cli api GET /open-apis/bitable/v1/...`;即使 wiki 解析结果是 `obj_type=bitable`,后续也应继续使用 `lark-cli base ...` 9. **不要把本地文件导入误判成 Base 表内操作** — 如果目标是“把 Excel / CSV / `.base` 快照导入成 Base / 多维表格”,必须先走 `lark-cli drive +import --type bitable`;只有导入完成后,才回到 `lark-cli base ...` @@ -34,13 +34,11 @@ - **Base token 口径统一**:无论 Shortcut 还是原生 API,都统一使用 `base_token` - **附件字段**:上传本地文件时只能走 `lark-cli base +record-upload-attachment` -- **人员字段 / 用户字段**:调试时注意 `user_id_type` 与执行身份(user / bot)差异 - **能力边界**:当前 `base/v3` 原生 spec 以单表 / 单记录 / 视图筛选配置为主,批量写入和旧 `search` 场景优先走 unified Shortcut 组合能力 - **视图重命名确认规则**:用户已经明确“把哪个视图改成什么名字”时,执行 `table.views patch` / 对应 shortcut 直接改名即可,不需要再补一句确认 - **删除确认规则(记录 / 字段 / 表)**:执行 `table.records delete / table.fields delete / tables delete` 或对应 shortcut 时,如果用户已经明确要求删除且目标明确,可以直接执行;只有目标不明确时才先追问 - **创建 / 复制 Base 的友好性规则**:创建或复制 Base 时,`folder_token`、`time_zone`、复制时的新名称都属于可选项;用户没特别要求时不要为这些参数额外打断 - **创建 / 复制 Base 的结果返回规范**:成功后必须主动返回新 Base 的 token;如果返回结果里带可访问链接(如 `base.url`),也要一并返回 -- **附件字段本地文件上传**:只能使用 `lark-cli base +record-upload-attachment` ## Wiki 链接特殊处理(特别关键!) @@ -103,18 +101,18 @@ lark-cli wiki spaces.get_node --params '{"token":"Pgrrwvr***********UnRb"}' | 错误码 | 含义 | 解决方案 | |--------|------|---------| -| 1254064 | 日期格式错误 | 用毫秒时间戳,非字符串 / 秒级 | -| 1254068 | 超链接格式错误 | 用 `{text, link}` 对象 | -| 1254066 | 人员字段错误 | 用 `[{id:"ou_xxx"}]`,并确认 `user_id_type` | +| 1254064 | 日期格式错误 | 传 `YYYY-MM-DD HH:mm:ss` 字符串,不要写相对时间 | +| 1254068 | 超链接格式错误 | `"https://example.com"` 或 `"[文本](https://example.com)"` | +| 1254066 | 人员字段错误 | `[{ "id": "ou_xxx" }]` | | 1254045 | 字段名不存在 | 检查字段名(含空格、大小写) | | 1254015 | 字段值类型不匹配 | 先 list 字段,再按类型构造 | | `param baseToken is invalid` / `base_token invalid` | 把 wiki token、workspace token 或其他 token 当成了 `base_token` | 如果输入来自 `/wiki/...`,先查 `wiki.spaces.get_node`;当 `obj_type=bitable` 时,用 `node.obj_token` 作为 `base_token` 重试,不要改走 `bitable/v1` | -| 1254104 | 批量超 500 条 | 分批调用 | +| 1254104 | 批量超 200 条 | 分批调用 | | 1254291 | 并发写冲突 | 串行写入 + 批次间延迟 | ## 参考文档 -- [lark-base-shortcut-field-properties.md](../../skills/lark-base/references/lark-base-shortcut-field-properties.md) — 字段类型 property 配置 -- [lark-base-shortcut-record-value.md](../../skills/lark-base/references/lark-base-shortcut-record-value.md) — 记录值格式详解 +- [lark-base-shortcut-field-properties.md](../../skills/lark-base/references/lark-base-shortcut-field-properties.md) — 字段类型 JSON 配置 +- [lark-base-cell-value.md](../../skills/lark-base/references/lark-base-cell-value.md) — CellValue source of truth - [lark-base-view-set-filter.md](../../skills/lark-base/references/lark-base-view-set-filter.md) — 查询筛选指南(filter / operator / sort / 分页) - [examples.md](../../skills/lark-base/references/examples.md) — 完整操作示例(建表、筛选、更新) diff --git a/skills/lark-base/SKILL.md b/skills/lark-base/SKILL.md index 74b4d919b..ccc3bf07b 100644 --- a/skills/lark-base/SKILL.md +++ b/skills/lark-base/SKILL.md @@ -103,7 +103,7 @@ metadata: | 命令 | 用途 / 何时使用 | 必读 reference | 路由提醒 | |------|------------------|----------------|----------| | `+record-search / +record-list / +record-get` | 按关键词检索记录、读取记录明细 / 分页导出,或获取单条记录详情 | [`lark-base-record-search.md`](references/lark-base-record-search.md)、[`lark-base-record-list.md`](references/lark-base-record-list.md)、[`lark-base-record-get.md`](references/lark-base-record-get.md) | 默认优先 `+record-list`;仅当用户提供明确搜索关键词时使用 `+record-search`;取数不用来做聚合分析;`--limit` 最大 `200`;仅在用户明确需要时继续翻页;`+record-list` 只能串行执行 | -| `+record-upsert / +record-batch-create / +record-batch-update` | 创建、更新或批量写入记录 | [`lark-base-record-upsert.md`](references/lark-base-record-upsert.md)、[`lark-base-record-batch-create.md`](references/lark-base-record-batch-create.md)、[`lark-base-record-batch-update.md`](references/lark-base-record-batch-update.md)、[`lark-base-shortcut-record-value.md`](references/lark-base-shortcut-record-value.md) | 写前先 `+field-list`;只写存储字段;`+record-batch-update` 为同值更新(同一 patch 应用到多条记录);批量单次不超过 `200` 条;附件不要走这里 | +| `+record-upsert / +record-batch-create / +record-batch-update` | 创建、更新或批量写入记录 | [`lark-base-record-upsert.md`](references/lark-base-record-upsert.md)、[`lark-base-record-batch-create.md`](references/lark-base-record-batch-create.md)、[`lark-base-record-batch-update.md`](references/lark-base-record-batch-update.md)、[`lark-base-cell-value.md`](references/lark-base-cell-value.md) | 写前先 `+field-list`;只写存储字段;`+record-batch-update` 为同值更新(同一 patch 应用到多条记录);批量单次不超过 `200` 条;附件不要走这里 | | `+record-upload-attachment` | 给已有记录上传附件 | [`lark-base-record-upload-attachment.md`](references/lark-base-record-upload-attachment.md) | 附件上传专用链路,不要用 `+record-upsert` / `+record-batch-*` 伪造附件值 | | `lark-cli docs +media-download` | 下载 Base 附件文件到本地 | [`../lark-doc/references/lark-doc-media-download.md`](../lark-doc/references/lark-doc-media-download.md) | Base 附件的 `file_token` 从 `+record-get` 返回的附件字段数组里取;**不要用 `lark-cli drive +download`**(对 Base 附件返回 403) | | `+record-delete / +record-history-list` | 删除记录,或查询某条记录的变更历史 | [`lark-base-record-delete.md`](references/lark-base-record-delete.md)、[`lark-base-record-history-list.md`](references/lark-base-record-history-list.md) | 删除时用户已明确目标可直接执行并带 `--yes`;历史查询按 `table-id + record-id`,不支持整表扫描;`+record-history-list` 只能串行执行 | @@ -273,10 +273,6 @@ lark-cli auth login --domain base 4. 若 bot 身份仍然返回权限错误,**立即停止重试**,根据错误响应按 `lark-shared` 流程引导用户解决(引导去开发者后台开通 scope 或确认资源访问权限)。 5. 只有在用户明确要求"用应用身份 / bot 身份操作",才跳过 user 直接使用 `--as bot`。 -**补充说明**: - -- 人员字段 / 用户字段:注意 `user_id_type` 与执行身份(user / bot)差异。 - ## 4. 执行规则 ### 4.1 标准执行顺序 @@ -293,7 +289,7 @@ lark-cli auth login --domain base 1. 先拿结构,再写命令;至少先拿当前表结构,跨表时还要拿目标表结构。 2. 不要猜表名、字段名、表达式引用,一律以真实返回为准。 3. 只使用原子命令;不要回退到旧的聚合式 `+table / +field / +record / +view / +history / +workspace`。 -4. 写记录前先读字段结构;先 `+field-list`,再按字段类型构造写入值。 +4. 写记录前先读字段结构;先 `+field-list`,再按 [`lark-base-cell-value.md`](references/lark-base-cell-value.md) 构造 CellValue。 5. 写字段前先看字段属性规范;先读 `lark-base-shortcut-field-properties.md`,再构造 `+field-create / +field-update` 的 JSON。 6. 只写可写字段;系统字段、附件字段、`formula`、`lookup` 默认不作为普通记录写入目标。 7. 聚合分析与取数分流;统计走 `+data-query`,关键词检索走 `+record-search`,明细走 `+record-list / +record-get`。 @@ -323,15 +319,15 @@ lark-cli auth login --domain base | 错误 / 现象 | 含义 | 恢复动作 | |-------------|------|----------| -| `1254064` | 日期格式错误 | 用毫秒时间戳,非字符串 / 秒级 | -| `1254068` | 超链接格式错误 | 用 `{text, link}` 对象 | -| `1254066` | 人员字段错误 | 用 `[{id:"ou_xxx"}]`,并确认 `user_id_type` | +| `1254064` | 日期格式错误 | 传 `YYYY-MM-DD HH:mm:ss` 字符串,不要写相对时间 | +| `1254068` | 超链接格式错误 | `"https://example.com"` 或 `"[文本](https://example.com)"` | +| `1254066` | 人员字段错误 | `[{ "id": "ou_xxx" }]` | | `1254045` | 字段名不存在 | 检查字段名(含空格、大小写) | | `1254015` | 字段值类型不匹配 | 先 `+field-list`,再按类型构造 | | `param baseToken is invalid` / `base_token invalid` | 把 wiki token、workspace token 或其他 token 当成了 `base_token` | 如果输入来自 `/wiki/...`,先用 `lark-cli wiki spaces get_node` 取真实 `obj_token`;当 `obj_type=bitable` 时,用 `node.obj_token` 作为 `--base-token` 重试,不要改走 `bitable/v1` | | `not found` 且用户给的是 wiki 链接 | 常见于把 wiki token 当成 base token | 优先回退检查 wiki 解析,而不是改走 `bitable/v1` | | formula / lookup 创建失败 | 指南未读或结构不合法 | 先读 `formula-field-guide.md` / `lookup-field-guide.md`,再按 guide 重建请求 | -| 系统字段 / 公式字段写入失败 | 只读字段被当成可写字段 | 改为写存储字段,计算结果交给 formula / lookup / 系统字段自动产出 | +| `ignored_fields` / `READONLY` | 只读字段被当成可写字段,常见于系统字段、formula、lookup | 移除只读字段,只写存储字段;计算结果交给 formula / lookup / 系统字段自动产出 | | `1254104` | 批量超 200 条 | 分批调用 | | `1254291` | 并发写冲突 | 串行写入 + 批次间延迟 | | `91403` | 无权限访问该 Base | **不要重试**。按 `lark-shared` 权限不足处理流程引导用户解决权限问题 | diff --git a/skills/lark-base/references/examples.md b/skills/lark-base/references/examples.md index 19d629417..8e6af92ff 100644 --- a/skills/lark-base/references/examples.md +++ b/skills/lark-base/references/examples.md @@ -2,7 +2,7 @@ 本文档提供基于 `lark-cli base ...` 的完整示例,覆盖 unified Shortcut 与当前 `base/v3` 原生 API 的常见组合方式。 -> **返回**: [SKILL.md](../SKILL.md) | **参考**: [shortcut 字段 JSON 规范](lark-base-shortcut-field-properties.md) · [shortcut 记录值规范](lark-base-shortcut-record-value.md) +> **返回**: [SKILL.md](../SKILL.md) | **参考**: [shortcut 字段 JSON 规范](lark-base-shortcut-field-properties.md) · [CellValue 规范](lark-base-cell-value.md) --- diff --git a/skills/lark-base/references/lark-base-cell-value.md b/skills/lark-base/references/lark-base-cell-value.md new file mode 100644 index 000000000..1c53e97db --- /dev/null +++ b/skills/lark-base/references/lark-base-cell-value.md @@ -0,0 +1,144 @@ +# base CellValue 规范(lark-base-cell-value) + +> 适用命令:`lark-cli base +record-upsert`、`lark-cli base +record-batch-create`、`lark-cli base +record-batch-update` + +本文件定义 **shortcut 写记录** 时 `CellValue` 的推荐格式,目标是让 AI 一次写对。不同命令的外层 JSON 形状不同,但每个 cell 都以本文为 source of truth。 + +## 1. 顶层规则(必须遵守) + +- `--json` 必须是 JSON 对象。 +- `+record-upsert`:顶层直接传字段映射:`{"字段名或字段ID": CellValue}`。 +- `+record-batch-create`:`rows` 是 `CellValue[][]`,列顺序由 `fields` 决定。 +- `+record-batch-update`:`patch` 是 `Map`,同一份 `patch` 会应用到所有 `record_id_list`。 +- 一次 payload 里同一字段只用一种 key(字段名或字段 ID),不要重复。 +- 写入前先 `+field-list` 获取字段 `type/style/multiple`,再构造值。 +- 需要清空字段时优先传 `null`(字段允许清空时)。 + +## 2. 各类型 CellValue + +### 2.1 text / phone / url + +用字符串。URL 字段也传 URL 字符串;普通文本里可以保留 Markdown 风格链接文本,平台会按字段类型处理。 + +```json +{ + "标题": "Hello", + "联系电话": "1380000000000", + "官网": "https://example.com" +} +``` + +### 2.2 number + +用 JSON number,不要用带单位或千分位的字符串。货币、百分比、进度、评分等数字类字段也按数字写入,展示格式由字段配置决定。 + +```json +{ + "工时": 12.5, + "预算": 3000, + "完成度": 0.65, + "评分": 4 +} +``` + +### 2.3 select(单选/多选) + +单选用选项名字符串;多选用选项名数组。选项名建议与字段配置一致;写入未知选项时平台可能自动新增选项,因此不要把自然语言近义词当成已有选项传入。 + +```json +{ + "单选": "Todo", + "多选": ["后端", "高优"] +} +``` + +### 2.4 datetime + +优先用 `YYYY-MM-DD HH:mm:ss` 字符串,这是最稳妥的写法,也和常见 API 输出更容易对齐。不要写相对时间(如“明天上午”)。 + +```json +{ + "截止时间": "2026-03-24 10:00:00" +} +``` + +### 2.5 checkbox + +用 JSON boolean:`true` 或 `false`,不要用 `"true"`、`"是"`、`1`。 + +```json +{ + "已完成": true +} +``` + +### 2.6 user + +用对象数组,元素至少包含 `id`。单选/多选人员字段都使用数组;`id` 必须是可被当前 Base 识别的用户 ID,写入前确认字段是否允许多选人员。 + +```json +{ + "负责人": [ + { "id": "ou_xxx" }, + { "id": "ou_xxx2" } + ] +} +``` + +### 2.7 link + +用对象数组,元素包含 `id`,值为目标记录的 `record_id`。不要传记录标题;先用 `+record-list` / `+record-search` 找到目标记录 ID。 + +```json +{ + "关联任务": [ + { "id": "" } + ] +} +``` + +### 2.8 location + +用对象 `{lng, lat}`,两者都是数字;`lng` 是经度,`lat` 是纬度。 + +```json +{ + "坐标": { + "lng": 116.397428, + "lat": 39.90923 + } +} +``` + +### 2.9 attachment(不作为普通 CellValue 写入) + +用户要把本地文件加到记录里时,必须使用 `lark-cli base +record-upload-attachment --file ` 上传到已有记录。不能用普通记录操作接口来上传附件。 + +`+record-get` 返回的附件字段单元格包含 `file_token` 和文件名,可以把 `file_token` 交给 `lark-cli docs +media-download` 进行附件下载。 + +## 3. 只读字段(不要写) + +以下字段在写记录时应视为只读: +- `auto_number` +- `lookup` +- `formula` +- `created_at` / `updated_at` +- `created_by` / `updated_by` + +写入只读字段通常不会更新数据;返回里可能出现 `ignored_fields`,reason 会说明 `READONLY`。看到这种返回时,不要重试同一 payload,应移除只读字段,只写存储字段。 + +## 4. 完整示例 + +```json +{ + "标题": "Created from shortcut", + "状态": "Todo", + "标签": ["高优", "外部依赖"], + "工时": 8, + "截止时间": "2026-03-24 10:00:00", + "已完成": false, + "负责人": [{ "id": "ou_123" }], + "关联任务": [{ "id": "rec_456" }], + "坐标": { "lng": 116.397428, "lat": 39.90923 } +} +``` diff --git a/skills/lark-base/references/lark-base-data-query.md b/skills/lark-base/references/lark-base-data-query.md index 6b351a1dd..97f030ce9 100644 --- a/skills/lark-base/references/lark-base-data-query.md +++ b/skills/lark-base/references/lark-base-data-query.md @@ -371,5 +371,5 @@ value 使用预定义关键字机制,第一个元素为字符串常量名称 - [lark-base](../SKILL.md) — 多维表格全部命令 - [lark-shared](../../lark-shared/SKILL.md) — 认证和全局参数 -- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — shortcut 字段值格式规范 +- [lark-base-cell-value.md](lark-base-cell-value.md) — CellValue 格式规范 - [lark-base-shortcut-field-properties.md](lark-base-shortcut-field-properties.md) — shortcut 字段类型与 JSON 结构 diff --git a/skills/lark-base/references/lark-base-record-batch-create.md b/skills/lark-base/references/lark-base-record-batch-create.md index 803883c25..fe336c234 100644 --- a/skills/lark-base/references/lark-base-record-batch-create.md +++ b/skills/lark-base/references/lark-base-record-batch-create.md @@ -6,23 +6,16 @@ ## 适用场景(重点) -- 适合大量创建写入场景,例如导入 CSV / Excel、外部系统一次性写入新数据。 -- 当输入是长表格或长文本数据时,先按 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) 做字段映射和类型规范化,再组装 `fields + rows` 调用本命令写入。 +- 适合导入 CSV / Excel、外部系统一次性写入新数据。 +- 先把输入数据映射到合适的字段类型,再组装 `fields + rows`。 ## 推荐命令 ```bash -lark-cli base +record-batch-create \ - --base-token XXXXXX \ - --table-id tblXXX \ +lark-cli base +record-batch-create --base-token --table-id \ --json '{"fields":["标题","状态"],"rows":[["任务 A","Open"],["任务 B","Done"]]}' -``` -```bash -lark-cli base +record-batch-create \ - --base-token XXXXXX \ - --table-id tblXXX \ - --json @batch-create.json +lark-cli base +record-batch-create --base-token --table-id --json @batch-create.json ``` ## 参数 @@ -33,44 +26,33 @@ lark-cli base +record-batch-create \ | `--table-id ` | 是 | 表 ID 或表名 | | `--json ` | 是 | 批量创建请求体,必须是 JSON 对象。支持直接传 JSON 字符串,或 `@` 从文件读取 | -## API 入参详情 +## API -**HTTP 方法和路径:** - -```http -POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records/batch_create -``` +`POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records/batch_create` ## `--json` 结构 +本节只说明 `+record-batch-create` 的外层 JSON 形状;CellValue 统一看 [lark-base-cell-value.md](lark-base-cell-value.md)。 + 对象形态:`{"fields":[...],"rows":[...]}`。 | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `fields` | `string[]` | 是 | 字段 ID 或字段名数组 | -| `rows` | `any[][]` | 是 | 二维数组,每一行按 `fields` 同序给值;单次最多 200 行 | +| `rows` | `CellValue[][]` | 是 | 二维数组,每一行按 `fields` 同序给 cell;单次最多 200 行 | ## 返回重点 -`data` 为多行二维数组,与 `+record-list` 返回的多行数据结构一致(按 `fields` 列顺序对齐)。 - -| 字段 | 类型 | 说明 | -|------|------|------| -| `fields` | `string[]` | 返回的字段名数组 | -| `field_id_list` | `string[]` | 返回的字段 ID 数组 | -| `record_id_list` | `string[]` | 新创建记录 ID 列表 | -| `data` | `any[][]` | 与 `fields` 对齐的多行数据 | -| `ignored_fields` | `array` | 可选,表示被忽略的字段信息 | +返回 `fields`、`field_id_list`、`record_id_list`、`data`,其中 `data` 与 `fields` 列顺序对齐。 ## 坑点 -- ⚠️ `--json` 必须是对象。 -- ⚠️ 写 `rows` 前必须先阅读 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md),按字段类型填值,禁止按自然语言猜测 value 结构。 -- ⚠️ `fields` 与 `rows` 列顺序必须一一对应。 -- ⚠️ 空单元格可以显式用 `null` 填充。 -- ⚠️ 单次最多 200 行,超出需分批写入。 +- `fields` 与每行 `rows` 的列顺序必须一一对应。 +- 空单元格必须显式用 `null` 填充。 +- 单次最多 200 行,超出需分批写入。 +- select 写入未知选项时平台可能自动新增选项;如果不是要新增选项,先确认真实选项名。 ## 参考 - [lark-base-record.md](lark-base-record.md) — record 索引页 -- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — 记录值格式规范 +- [lark-base-cell-value.md](lark-base-cell-value.md) — CellValue 格式规范 diff --git a/skills/lark-base/references/lark-base-record-batch-update.md b/skills/lark-base/references/lark-base-record-batch-update.md index 7014e2dfa..c93bd5c09 100644 --- a/skills/lark-base/references/lark-base-record-batch-update.md +++ b/skills/lark-base/references/lark-base-record-batch-update.md @@ -7,17 +7,10 @@ ## 推荐命令 ```bash -lark-cli base +record-batch-update \ - --base-token XXXXXX \ - --table-id tblXXX \ - --json '{"record_id_list":["recXXX"],"patch":{"field_id_or_name":"value"}}' -``` +lark-cli base +record-batch-update --base-token --table-id \ + --json '{"record_id_list":[""],"patch":{"状态":"完成"}}' -```bash -lark-cli base +record-batch-update \ - --base-token XXXXXX \ - --table-id tblXXX \ - --json @batch-update.json +lark-cli base +record-batch-update --base-token --table-id --json @batch-update.json ``` ## 参数 @@ -28,44 +21,33 @@ lark-cli base +record-batch-update \ | `--table-id ` | 是 | 表 ID 或表名 | | `--json ` | 是 | 批量更新请求体,必须是 JSON 对象。支持直接传 JSON 字符串,或 `@` 从文件读取 | -## 生成 `patch` 前必看 +## API -- 先阅读 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md),按字段类型构造 `patch` 的 value,避免类型不匹配。 - -## API 入参详情 - -**HTTP 方法和路径:** - -```http -POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records/batch_update -``` +`POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records/batch_update` ## `--json` 结构 +本节只说明 `+record-batch-update` 的外层 JSON 形状;CellValue 统一看 [lark-base-cell-value.md](lark-base-cell-value.md)。 + 对象形态:`{"record_id_list":[...],"patch":{...}}`。 | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `record_id_list` | `string[]` | 是 | 要更新的记录 ID 列表(单次最多 200 条) | -| `patch` | `object` | 是 | 同一份字段更新对象,会应用到 `record_id_list` 内所有记录 | +| `patch` | `Map` | 是 | 字段更新对象;key 是字段名或字段 ID,value 是 `CellValue`;同一份 `patch` 会应用到 `record_id_list` 内所有记录 | ## 返回重点 -返回结构如下(其中 `update` 可与 `+record-list` 的单行字段对象结构对齐): - -| 字段 | 类型 | 说明 | -|------|------|------| -| `record_id_list` | `string[]` | 本次更新到的记录 ID 列表 | -| `update` | `object` | 本次应用的字段更新结果;可能为空对象 | -| `ignored_fields` | `{id,name,reason}[]` | 可选,被忽略字段信息 | +返回 `record_id_list`、`update`,可选返回 `ignored_fields`;`update` 可能为空对象。 ## 坑点 -- ⚠️ `--json` 必须是对象。 -- ⚠️ 该接口是“同值批量更新”:同一请求内所有 `record_id_list` 都会应用同一份 `patch`。 -- ⚠️ `record_id_list` 最大 200 条,超过会被接口校验拒绝。 -- ⚠️ 命令不会自动做字段/行映射转换,传什么就发什么。 +- 这是“同值批量更新”:所有 `record_id_list` 都应用同一份 `patch`。 +- `record_id_list` 最大 200 条,超过会被接口校验拒绝。 +- 命令不会自动做字段/行映射转换,传什么就发什么。 +- 如果 `patch` 包含只读字段,返回里可能出现 `ignored_fields`;这些字段不会被更新。 ## 参考 - [lark-base-record.md](lark-base-record.md) — record 索引页 +- [lark-base-cell-value.md](lark-base-cell-value.md) — CellValue 格式规范 diff --git a/skills/lark-base/references/lark-base-record-delete.md b/skills/lark-base/references/lark-base-record-delete.md index e9fd1f2dc..203e30d6d 100644 --- a/skills/lark-base/references/lark-base-record-delete.md +++ b/skills/lark-base/references/lark-base-record-delete.md @@ -8,9 +8,9 @@ ```bash lark-cli base +record-delete \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --record-id rec_xxx \ + --base-token \ + --table-id \ + --record-id \ --yes ``` diff --git a/skills/lark-base/references/lark-base-record-get.md b/skills/lark-base/references/lark-base-record-get.md index 6499126bd..bc9549135 100644 --- a/skills/lark-base/references/lark-base-record-get.md +++ b/skills/lark-base/references/lark-base-record-get.md @@ -8,9 +8,9 @@ ```bash lark-cli base +record-get \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --record-id rec_xxx + --base-token \ + --table-id \ + --record-id ``` ## 参数 diff --git a/skills/lark-base/references/lark-base-record-history-list.md b/skills/lark-base/references/lark-base-record-history-list.md index caab7fbe8..8d55c3aa3 100644 --- a/skills/lark-base/references/lark-base-record-history-list.md +++ b/skills/lark-base/references/lark-base-record-history-list.md @@ -9,15 +9,15 @@ ```bash # 查询最新一页历史 lark-cli base +record-history-list \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --record-id rec_xxx + --base-token \ + --table-id \ + --record-id # 指定分页大小,带游标翻页 lark-cli base +record-history-list \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --record-id rec_xxx \ + --base-token \ + --table-id \ + --record-id \ --page-size 30 \ --max-version 123456 ``` diff --git a/skills/lark-base/references/lark-base-record-list.md b/skills/lark-base/references/lark-base-record-list.md index e7d74ed14..2d6177a3e 100644 --- a/skills/lark-base/references/lark-base-record-list.md +++ b/skills/lark-base/references/lark-base-record-list.md @@ -32,15 +32,15 @@ ```bash lark-cli base +record-list \ - --base-token XXXXXX \ - --table-id tblXXX \ + --base-token \ + --table-id \ --offset 0 \ --limit 100 lark-cli base +record-list \ - --base-token XXXXXX \ - --table-id tblXXX \ - --view-id vewXXX \ + --base-token \ + --table-id \ + --view-id \ --field-id fldStatus \ --field-id 项目名称 \ --offset 0 \ diff --git a/skills/lark-base/references/lark-base-record-search.md b/skills/lark-base/references/lark-base-record-search.md index d4cbf6e2d..d4d88ca2a 100644 --- a/skills/lark-base/references/lark-base-record-search.md +++ b/skills/lark-base/references/lark-base-record-search.md @@ -15,14 +15,14 @@ ```bash lark-cli base +record-search \ - --base-token XXXXXX \ - --table-id tblXXX \ - --json '{"keyword":"Created","search_fields":["Title","fld_owner"],"offset":0,"limit":100}' + --base-token \ + --table-id \ + --json '{"keyword":"Created","search_fields":["Title",""],"offset":0,"limit":100}' lark-cli base +record-search \ - --base-token XXXXXX \ - --table-id tblXXX \ - --json '{"view_id":"vewXXX","keyword":"Alice","search_fields":["Title","Owner"],"select_fields":["Title","Owner","Status"],"offset":0,"limit":50}' + --base-token \ + --table-id \ + --json '{"view_id":"","keyword":"Alice","search_fields":["Title","Owner"],"select_fields":["Title","Owner","Status"],"offset":0,"limit":50}' ``` ## 参数 diff --git a/skills/lark-base/references/lark-base-record-share-link-create.md b/skills/lark-base/references/lark-base-record-share-link-create.md index df9c8ac58..9c46f49bd 100644 --- a/skills/lark-base/references/lark-base-record-share-link-create.md +++ b/skills/lark-base/references/lark-base-record-share-link-create.md @@ -9,14 +9,14 @@ ```bash # 单条记录 lark-cli base +record-share-link-create \ - --base-token xxx \ - --table-id tbl_xxx \ - --record-ids rec_xxx + --base-token \ + --table-id \ + --record-ids # 多条记录(使用 "," 分隔) lark-cli base +record-share-link-create \ - --base-token xxx \ - --table-id tbl_xxx \ + --base-token \ + --table-id \ --record-ids rec001,rec002,rec003 ``` diff --git a/skills/lark-base/references/lark-base-record-upload-attachment.md b/skills/lark-base/references/lark-base-record-upload-attachment.md index 6e530d1a4..45abe0ba4 100644 --- a/skills/lark-base/references/lark-base-record-upload-attachment.md +++ b/skills/lark-base/references/lark-base-record-upload-attachment.md @@ -8,16 +8,16 @@ ```bash lark-cli base +record-upload-attachment \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --record-id rec_xxx \ - --field-id fld_attach \ + --base-token \ + --table-id \ + --record-id \ + --field-id \ --file ./report.pdf lark-cli base +record-upload-attachment \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --record-id rec_xxx \ + --base-token \ + --table-id \ + --record-id \ --field-id "附件" \ --file ./report.pdf \ --name "Q1-final.pdf" @@ -48,4 +48,3 @@ lark-cli base +record-upload-attachment \ ## 参考 - [lark-base-record.md](lark-base-record.md) — record 索引页 -- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — 记录值格式详解 diff --git a/skills/lark-base/references/lark-base-record-upsert.md b/skills/lark-base/references/lark-base-record-upsert.md index 208616333..6634504a6 100644 --- a/skills/lark-base/references/lark-base-record-upsert.md +++ b/skills/lark-base/references/lark-base-record-upsert.md @@ -7,16 +7,13 @@ ## 推荐命令 ```bash -lark-cli base +record-upsert \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --json '{"项目名称":"Apollo","状态":"进行中"}' +# 创建记录 +lark-cli base +record-upsert --base-token --table-id \ + --json '{"项目名称":"Apollo","状态":"进行中"}' -lark-cli base +record-upsert \ - --base-token app_xxx \ - --table-id tbl_xxx \ - --record-id rec_xxx \ - --json '{"项目名称":"Apollo","状态":"进行中","标签":["高优","外部依赖"],"截止日期":"2026-03-24 10:00:00"}' +# 更新记录 +lark-cli base +record-upsert --base-token --table-id --record-id \ + --json '{"项目名称":"Apollo","状态":"完成","完成时间":"2026-03-24 10:00:00"}' ``` ## 参数 @@ -26,44 +23,26 @@ lark-cli base +record-upsert \ | `--base-token ` | 是 | Base Token | | `--table-id ` | 是 | 表 ID 或表名 | | `--record-id ` | 否 | 传入时走更新,不传时走创建 | -| `--json ` | 是 | 记录 JSON 对象 | +| `--json ` | 是 | 字段写入对象,类型 `Map` | -## API 入参详情 +## API -**HTTP 方法和路径:** +- 创建:`POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records` +- 更新:带 `--record-id` 时改走 `PATCH /records/:record_id` -``` -POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records -``` +## `--json` 结构 -- 带 `--record-id` 时内部改走 `PATCH /records/:record_id`。 - -## JSON 值规范 - -- `--json` 必须是 **JSON 对象**。 -- key 可用字段名或字段 ID,但一次请求里同一字段只用一种标识,避免重复写入冲突。 -- value 必须匹配字段类型;先 `+field-list` 再构造值。 -- 推荐值形状(常用): - - 文本:`"标题"` - - 数字:`12.5` - - 单选:`"Todo"` - - 多选:`["A","B"]` - - 复选框:`true` - - 人员:`[{"id":"ou_xxx"}]` - - 关联记录:`[{"id":"rec_xxx"}]` - - 日期:`"YYYY-MM-DD HH:mm:ss"`(如 `"2026-03-24 10:00:00"`) -- 需要清空字段时优先传 `null`(字段允许清空时)。 -- 公式、查找引用、创建/更新时间、创建/修改人等只读字段不要写入。 - -**正确(base +record-upsert)** +- `--json` 必须是 **JSON object map**,形状是 `Map`。 +- key 是字段名或字段 ID;value 是该字段的 `CellValue`。 +- 一次请求里同一字段只用一种标识,避免重复写入冲突。 +- 写入前先 `+field-list` 确认字段类型和字段名/ID。 +- CellValue 统一看 [lark-base-cell-value.md](lark-base-cell-value.md)。 ```json { "项目名称": "Apollo", "状态": "进行中", - "标签": ["高优", "外部依赖"], - "负责人": [{ "id": "ou_xxx" }], - "截止日期": "2026-03-24 10:00:00" + "完成时间": "2026-03-24 10:00:00" } ``` @@ -71,19 +50,15 @@ POST /open-apis/base/v3/bases/:base_token/tables/:table_id/records - 创建时返回 `record` 和 `created: true`。 - 更新时返回 `record` 和 `updated: true`。 - -## 工作流 - - -1. 先确定是新增还是修改。 +- 如果写入了 `formula / lookup / created_at / updated_at / created_by / updated_by` 等只读字段,返回里可能出现 `ignored_fields`,这些字段不会被更新。 ## 坑点 -- ⚠️ `--json` 必须是对象,不支持数组。 -- ⚠️ 有 `--record-id` 就一定走更新;不传就一定走创建,不会自动查重。 -- ⚠️ 这是写入操作,执行前必须确认。 +- 有 `--record-id` 就一定更新;不传就一定创建,不会自动查重或按业务键 upsert。 +- select 写入未知选项时平台可能自动新增选项;如果不是要新增选项,先用 `+field-list` / `+field-search-options` 确认真实选项名。 +- 这是写入操作,执行前必须确认目标表和字段。 ## 参考 - [lark-base-record.md](lark-base-record.md) — record 索引页 -- [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md) — shortcut 记录值格式规范(推荐) +- [lark-base-cell-value.md](lark-base-cell-value.md) — CellValue 格式规范 diff --git a/skills/lark-base/references/lark-base-record.md b/skills/lark-base/references/lark-base-record.md index 3638c9d8d..46fa54844 100644 --- a/skills/lark-base/references/lark-base-record.md +++ b/skills/lark-base/references/lark-base-record.md @@ -24,6 +24,6 @@ record 相关命令索引。 - 聚合页只保留目录职责;每个命令的详细说明请进入对应单命令文档。 - 所有 `+xxx-list` 调用都必须串行执行;若要批量跑多个 list 请求,只能串行执行。 - `+record-list` 支持重复传参 `--field-id` 做字段筛选。 -- 写记录 JSON 前优先阅读 [lark-base-shortcut-record-value.md](lark-base-shortcut-record-value.md)。 +- 写记录 JSON 前优先阅读 [lark-base-cell-value.md](lark-base-cell-value.md)。 - 本地文件写入附件字段时,必须使用 `+record-upload-attachment`。 - 从附件字段下载文件时,用 `lark-cli docs +media-download --token --output `,用法见 [`../../lark-doc/references/lark-doc-media-download.md`](../../lark-doc/references/lark-doc-media-download.md)。 diff --git a/skills/lark-base/references/lark-base-shortcut-record-value.md b/skills/lark-base/references/lark-base-shortcut-record-value.md deleted file mode 100644 index 8d8e42b27..000000000 --- a/skills/lark-base/references/lark-base-shortcut-record-value.md +++ /dev/null @@ -1,200 +0,0 @@ -# base shortcut record JSON 规范(lark-base-shortcut-record-value) - -> 适用命令:`lark-cli base +record-upsert` - -本文件定义 **shortcut 写记录** 时 `--json` 的推荐格式,目标是让 AI 一次写对。 - -## 1. 顶层规则(必须遵守) - -- `--json` 必须是 JSON 对象。 -- 顶层直接传字段映射:`{"字段名或字段ID": 值}`。 -- 一次 payload 里同一字段只用一种 key(字段名或字段 ID),不要重复。 -- 写入前先 `+field-list` 获取字段 `type/style/multiple`,再构造值。 - -## 2. 各类型值格式与示例 - -### 2.1 text / phone / url - -**推荐值**:字符串。 - -```json -{ - "标题": "Hello", - "联系电话": "1380000000000", - "官网": "https://example.com" -} -``` - -**Schema** - -```json -{ "type": "string", "description": "text field cell, example: \"one string and [one url](https://foo.bar)\"" } -``` - -### 2.2 number - -**推荐值**:数字。 - -```json -{ - "工时": 12.5, - "预算": 3000 -} -``` - -**Schema** - -```json -{ "type": "number", "description": "number field cell, can be any float64 value" } -``` - -### 2.3 select(单选/多选/阶段) - -**推荐值**: -- 单选:字符串 -- 多选:字符串数组 - -```json -{ - "状态": "Todo", - "标签": ["后端", "高优"] -} -``` - -**Schema** - -```json -{ "type": "array", "items": { "type": "string", "description": "option name" }, "description": "select field cell, example: [\"option_1\", \"option_2\"]" } -``` - -### 2.4 datetime - -**推荐值**:`YYYY-MM-DD HH:mm:ss` 字符串(稳妥写法)。 - -```json -{ - "截止时间": "2026-03-24 10:00:00" -} -``` - -**Schema** - -```json -{ "type": "string", "description": "datetime field cell. accepts common datetime strings and timestamp-like values. Prefer \"YYYY-MM-DD HH:mm:ss\" in requests because it is the most stable format and matches the API output. Example: \"2026-01-01 19:30:00\"" } -``` - -### 2.5 checkbox - -**推荐值**:布尔值。 - -```json -{ - "已完成": true -} -``` - -**Schema** - -```json -{ "type": "boolean", "description": "checkbox field cell" } -``` - -### 2.6 user - -**推荐值**:对象数组,元素至少有 `id`。 - -```json -{ - "负责人": [ - { "id": "ou_xxx" } - ] -} -``` - -**Schema** - -```json -{ "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "user id" } }, "required": ["id"], "additionalProperties": false }, "description": "user field cell, example: [{\"id\": \"ou_123\"}]" } -``` - -### 2.7 link - -**推荐值**:对象数组,元素至少有 `id`。 - -```json -{ - "关联任务": [ - { "id": "rec_xxx" } - ] -} -``` - -**Schema** - -```json -{ "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string", "description": "record id" } }, "required": ["id"], "additionalProperties": false }, "description": "link field cell, example: [{\"id\": \"rec_123\"}]" } -``` - -### 2.8 location - -**推荐值**:对象 `{lng, lat}`。 - -```json -{ - "坐标": { - "lng": 116.397428, - "lat": 39.90923 - } -} -``` - -**Schema** - -```json -{ - "type": "object", - "properties": { "lng": { "type": "number", "description": "Longitude" }, "lat": { "type": "number", "description": "Latitude" } }, - "required": ["lng", "lat"], - "additionalProperties": false, - "description": "location field cell, example: {\"lng\": 113.94765, \"lat\": 22.528533}" -} -``` - -### 2.9 attachment - -对 agent 而言,附件上传是**特殊链路**:如果用户要把本地文件加到记录里,必须使用 `lark-cli base +record-upload-attachment` 上传到已有记录。 - -**Schema - attachment** - -```json -{ - "type": "array", - "items": { "type": "object", "properties": { "file_token": { "type": "string", "minLength": 0, "maxLength": 50 }, "name": { "type": "string", "minLength": 1, "maxLength": 255 } }, "required": ["file_token", "name"], "additionalProperties": false }, - "description": "attachment field cell. For agent, do not synthesize this payload via +record-upsert; must use +record-upload-attachment to upload files." -} -``` - -## 3. 只读字段(不要写) - -以下字段在写记录时应视为只读: -- `auto_number` -- `lookup` -- `formula` -- `created_time` / `modified_time` -- `created_by` / `modified_by` - -## 4. 快速可用完整示例 - -```json -{ - "标题": "Created from shortcut", - "状态": "Todo", - "标签": ["高优", "外部依赖"], - "工时": 8, - "截止时间": "2026-03-24 10:00:00", - "已完成": false, - "负责人": [{ "id": "ou_123" }], - "关联任务": [{ "id": "rec_456" }], - "坐标": { "lng": 116.397428, "lat": 39.90923 } -} -```