# 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":"..."}` 对象 | | 对只读字段写入值 | 不传该字段,由系统自动填充 |