347 lines
8.6 KiB
Markdown
347 lines
8.6 KiB
Markdown
# cells 写入/读取格式规范(cellValue 数据结构)
|
||
|
||
> 适用命令:`dws aitable record create --records`、`dws aitable record update --records`、`dws aitable record query` 返回
|
||
>
|
||
> 本文件是 DWS AI 表格 cellValue 的 **source of truth**。写入记录时,必须严格按此格式构造 cells 对象。
|
||
|
||
## 顶层规则
|
||
|
||
- cells 的 key **必须是 fieldId**(如 `fldXXX`),不是字段名称
|
||
- fieldId 必须从 `field get` 返回中获取
|
||
- 不同字段类型的 value 格式不同,混用会报错
|
||
- 系统只读字段(creator/lastModifier/createdTime/lastModifiedTime/formula)不可写入
|
||
|
||
## 各字段类型详解
|
||
|
||
### text(文本)
|
||
|
||
**写入**:字符串
|
||
```json
|
||
{"fldTextId": "这是一段文本"}
|
||
```
|
||
|
||
**读取**:字符串
|
||
```json
|
||
{"fldTextId": "这是一段文本"}
|
||
```
|
||
|
||
---
|
||
|
||
### number(数字)
|
||
|
||
**写入**:数字或数字字符串
|
||
```json
|
||
{"fldNumId": 123.45}
|
||
{"fldNumId": "123.45"}
|
||
```
|
||
|
||
**读取**:字符串形式的数字
|
||
```json
|
||
{"fldNumId": "123.45"}
|
||
```
|
||
|
||
---
|
||
|
||
### singleSelect(单选)
|
||
|
||
**写入**:选项名称字符串(推荐),或对象形式 `{id, name}`
|
||
```json
|
||
{"fldSelectId": "进行中"}
|
||
{"fldSelectId": {"id": "opt_xxx", "name": "进行中"}}
|
||
```
|
||
|
||
> 写入不存在的选项名称时,系统会自动创建该选项。
|
||
> 对象写入时 id 为准,服务端会校验 id 是否存在。
|
||
|
||
**读取**:对象 `{id, name}`
|
||
```json
|
||
{"fldSelectId": {"id": "opt_abc123", "name": "进行中"}}
|
||
```
|
||
|
||
---
|
||
|
||
### multipleSelect(多选)
|
||
|
||
**写入**:选项名称数组(推荐),或对象数组
|
||
```json
|
||
{"fldMultiId": ["标签A", "标签B"]}
|
||
{"fldMultiId": [{"id": "opt_a", "name": "标签A"}, {"id": "opt_b", "name": "标签B"}]}
|
||
```
|
||
|
||
> 写入时每项需带 id(对象模式)或直接传 name 字符串。不存在的 name 会自动补入选项配置。
|
||
|
||
**读取**:对象数组
|
||
```json
|
||
{"fldMultiId": [{"id": "opt_a", "name": "标签A"}, {"id": "opt_b", "name": "标签B"}]}
|
||
```
|
||
|
||
---
|
||
|
||
### date(日期)
|
||
|
||
**写入**:日期字符串、RFC3339 字符串、或毫秒时间戳
|
||
```json
|
||
{"fldDateId": "2026-03-15"}
|
||
{"fldDateId": "2026-03-15 09:00"}
|
||
{"fldDateId": "2026-03-15T09:00+08:00"}
|
||
```
|
||
|
||
**读取**:RFC3339 字符串(带时区)
|
||
```json
|
||
{"fldDateId": "2026-03-15T09:00:00+08:00"}
|
||
```
|
||
|
||
**过滤**(`record query --filters`):日期字段**只能用日期专用操作符** `date_eq` / `before` / `after` / `not_before` / `not_after` / `exist` / `un_exist`,比较值用日期字符串(如 `"2026-03-15"`)。
|
||
- ❌ 通用 `eq` / `ne` / `gt` / `gte` / `lt` / `lte` / `contain` 对日期字段无效,会静默返回 0 条;
|
||
- ❌ 不支持区间 `date_between` 与相对 `from_now`(CLI 会直接拒绝),范围查询用 `not_before` + `not_after` 组合。
|
||
- 详见 [aitable-filter-sort.md](./aitable-filter-sort.md) §日期字段过滤。
|
||
|
||
---
|
||
|
||
### currency(货币)
|
||
|
||
**写入**:数字(与 number 相同)
|
||
```json
|
||
{"fldCurrencyId": 99.5}
|
||
```
|
||
|
||
**读取**:字符串形式的数字(小数位数取决于 formatter 配置)
|
||
```json
|
||
{"fldCurrencyId": "99.5"}
|
||
```
|
||
|
||
---
|
||
|
||
### progress(进度)
|
||
|
||
**写入**:0~1 之间的浮点数(0 表示 0%,1 表示 100%)
|
||
```json
|
||
{"fldProgressId": 0.75}
|
||
```
|
||
|
||
> ⚠️ **常见错误**:写入 75 不会报错,但会被存储为 7500%(因为系统将其理解为 75 倍)。
|
||
> 正确做法:75% 应写入 0.75。API 不会拒绝超出 [0,1] 的值,但显示会异常。
|
||
> 如果字段配置了 `customizeRange`,则按自定义范围传值。
|
||
|
||
**读取**:字符串形式的数字
|
||
```json
|
||
{"fldProgressId": "0.75"}
|
||
```
|
||
|
||
---
|
||
|
||
### rating(评分)
|
||
|
||
**写入**:整数,必须在字段配置的 min~max 范围内
|
||
```json
|
||
{"fldRatingId": 4}
|
||
```
|
||
|
||
> ⚠️ 超出 max 范围的值(如 max=5 时写入 6)会被服务端拒绝并返回错误。
|
||
|
||
**读取**:数字(字符串形式)
|
||
```json
|
||
{"fldRatingId": "4"}
|
||
```
|
||
|
||
---
|
||
|
||
### checkbox(勾选)
|
||
|
||
**写入**:布尔值
|
||
```json
|
||
{"fldCheckId": true}
|
||
{"fldCheckId": false}
|
||
```
|
||
|
||
**读取**:布尔值
|
||
```json
|
||
{"fldCheckId": true}
|
||
```
|
||
|
||
---
|
||
|
||
### user(人员)
|
||
|
||
**写入**:对象数组,每项必须含 `userId` 和 `corpId`
|
||
```json
|
||
{"fldUserId": [{"userId": "staff_001", "corpId": "dingxxxxxxxx"}]}
|
||
```
|
||
|
||
> 单选字段(`multiple=false`)也必须传数组,只是数组长度为 1。
|
||
> 如果目标用户不在当前请求组织内,回退为 `[{"userRef": "ur_0AaZ19"}]`。
|
||
|
||
**读取**:对象数组
|
||
```json
|
||
{"fldUserId": [{"userId": "staff_001", "corpId": "dingxxxxxxxx"}]}
|
||
```
|
||
|
||
---
|
||
|
||
### department(部门)
|
||
|
||
**写入**:对象数组,每项含 `deptId`
|
||
```json
|
||
{"fldDeptId": [{"deptId": "52528700"}]}
|
||
```
|
||
|
||
**读取**:对象数组
|
||
```json
|
||
{"fldDeptId": [{"deptId": "52528700"}]}
|
||
```
|
||
|
||
---
|
||
|
||
### group(群组)
|
||
|
||
**写入**:对象数组,每项含 `cid`
|
||
```json
|
||
{"fldGroupId": [{"cid": "74577067501"}]}
|
||
```
|
||
|
||
> ⚠️ key 是 **`cid`**,不是 `openConversationId`
|
||
|
||
**读取**:对象数组
|
||
```json
|
||
{"fldGroupId": [{"cid": "74577067501"}]}
|
||
```
|
||
|
||
---
|
||
|
||
### url(链接)
|
||
|
||
**写入**:对象 `{text, link}` 或纯 URL 字符串
|
||
```json
|
||
{"fldUrlId": {"text": "钉钉官网", "link": "https://dingtalk.com"}}
|
||
{"fldUrlId": "https://dingtalk.com"}
|
||
```
|
||
|
||
> 纯字符串写入时,服务端自动补齐为 `{"text":"原字符串","link":"原字符串"}`
|
||
|
||
**读取**:对象 `{text, link}`
|
||
```json
|
||
{"fldUrlId": {"text": "钉钉官网", "link": "https://dingtalk.com"}}
|
||
```
|
||
|
||
---
|
||
|
||
### richText(富文本)
|
||
|
||
**写入**:对象 `{markdown: "..."}`
|
||
```json
|
||
{"fldRichId": {"markdown": "**加粗**\n普通文字\n"}}
|
||
```
|
||
|
||
**读取**:对象 `{markdown: "..."}`(有损,颜色/@人等信息可能丢失)
|
||
```json
|
||
{"fldRichId": {"markdown": "**加粗**\n普通文字\n"}}
|
||
```
|
||
|
||
---
|
||
|
||
### attachment(附件)
|
||
|
||
**写入**:对象数组,**必须使用 `fileToken`**
|
||
|
||
```json
|
||
{"fldAttachId": [{"fileToken": "ft_xxx"}]}
|
||
```
|
||
|
||
> ⚠️ **必须先通过 [attachment upload 流程](./aitable-attachment.md) 上传文件获取 `fileToken`,再将 `fileToken` 写入 cells。**
|
||
> ❌ **严禁直接传 `{"url": "https://..."}` 形式写入附件/图片字段** — 服务端会同步下载图片,10 条记录即触发 TIMEOUT_ERROR 超时。
|
||
> 写入会**整体覆盖**原附件列表,不是追加。
|
||
|
||
**读取**:对象数组(含下载链接、文件名、大小)
|
||
```json
|
||
{"fldAttachId": [{"url": "https://...", "filename": "report.pdf", "size": 204800}]}
|
||
```
|
||
|
||
---
|
||
|
||
### telephone / email / barcode / idCard(电话/邮箱/条码/身份证)
|
||
|
||
**写入**:字符串
|
||
```json
|
||
{"fldPhoneId": "13800138000"}
|
||
{"fldEmailId": "test@example.com"}
|
||
{"fldBarcodeId": "978-3-16-148410-0"}
|
||
{"fldIdCardId": "520402196001067498"}
|
||
```
|
||
|
||
> idCard 必须是后端认可的合法身份证号格式
|
||
|
||
**读取**:字符串
|
||
```json
|
||
{"fldPhoneId": "13800138000"}
|
||
```
|
||
|
||
---
|
||
|
||
### geolocation(地理位置)
|
||
|
||
**写入**:对象,包含 `address`、`name`、`location`
|
||
```json
|
||
{
|
||
"fldGeoId": {
|
||
"address": "浙江省杭州市思凯路与爱橙街交叉口东南200米",
|
||
"name": "阿里中心·未科D1幢",
|
||
"location": ["120.007852", "30.271194"]
|
||
}
|
||
}
|
||
```
|
||
|
||
> `location` 按 **[经度, 纬度]** 传**字符串数组**
|
||
|
||
**读取**:对象(含额外的 `fullAddress` 字段,由服务端自动拼接)
|
||
```json
|
||
{
|
||
"fldGeoId": {
|
||
"address": "浙江省杭州市",
|
||
"fullAddress": "阿里中心-浙江省杭州市",
|
||
"name": "阿里中心",
|
||
"location": ["120.007852", "30.271194"]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### unidirectionalLink / bidirectionalLink(关联字段)
|
||
|
||
**写入**:对象 `{linkedRecordIds: [...]}`
|
||
```json
|
||
{"fldLinkId": {"linkedRecordIds": ["recXXX", "recYYY"]}}
|
||
```
|
||
|
||
**读取**:对象 `{linkedRecordIds: [...]}`
|
||
```json
|
||
{"fldLinkId": {"linkedRecordIds": ["recXXX", "recYYY"]}}
|
||
```
|
||
|
||
---
|
||
|
||
### 只读字段(禁止写入)
|
||
|
||
以下字段类型由系统自动填充,`record create/update` 时**禁止传入**:
|
||
|
||
| 类型 | 说明 |
|
||
|------|------|
|
||
| `creator` | 创建人 |
|
||
| `lastModifier` | 最后编辑人 |
|
||
| `createdTime` | 创建时间 |
|
||
| `lastModifiedTime` | 最后编辑时间 |
|
||
| `formula` | 公式字段(系统计算) |
|
||
| AI 字段 | 由 AI 自动计算 |
|
||
|
||
## 常见错误速查
|
||
|
||
| 错误 | 正确做法 |
|
||
|------|----------|
|
||
| cells key 用字段名称 `"课程名称"` | 用 fieldId `"fldXXX"` |
|
||
| progress 写入 `75` | 写入 `0.75`(范围 0~1) |
|
||
| attachment 直接传文件路径或图片 URL | 必须先 `attachment upload` 获取 fileToken,再用 fileToken 写入(直传 URL 会超时) |
|
||
| user 字段传用户名字符串 | 传对象数组 `[{"userId":"...", "corpId":"..."}]` |
|
||
| group 字段用 `openConversationId` | 用 `cid` |
|
||
| singleSelect 传 option id 字符串 | 传 name 字符串或 `{"id":"...", "name":"..."}` 对象 |
|
||
| 对只读字段写入值 | 不传该字段,由系统自动填充 |
|