PicoBot/skills/lark-sheets/references/lark-sheets-pivot-table.md
ooodc a7883dbed9 refactor(todo): 重构待办事项管理逻辑及更新状态规则
- 移除 TodoItem 中的 priority、created_at 和 updated_at 字段
- 强制每个任务都必须有唯一 id,且由用户负责生成
- 修改合并模式逻辑,merge=true 下保留未提及的旧任务
- 支持已完成和已取消任务重新激活(状态改回 pending 或 in_progress)
- 禁止 in_progress 状态退回到 pending,必须标记为 completed 或 cancelled
- 优化状态转换校验,允许特定状态间合法切换
- 简化任务变更消息,移除详细的新增/更新/移除统计
- 更新文档和示例,明确 id 必须由用户生成和使用
- 修复和补充测试,增强状态转换和合并模式验证
- 调整任务时间戳生成逻辑,统一使用当前时间及索引
- 该变更提供更合理的任务状态机械及管理模式,提升稳定性和易用性
2026-06-13 09:22:33 +08:00

167 lines
12 KiB
Markdown
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.

# Lark Sheet Pivot Table
## 真对象硬约束
当用户要求"透视表 / 分组汇总 / 交叉分析 / 按 X 统计 Y"时,**必须**通过 `+pivot-{create|update|delete}` 创建真实的透视表对象。**禁止**用 `SUMIFS` / `COUNTIFS` 等普通公式 + `+cells-set` 在原表中拼一张"看起来像透视表的汇总表"来代替。判断标准:交付后 `+pivot-list` 必须能返回该对象。
## 使用场景
读写透视表对象。本 reference 覆盖 4 个 shortcut
| 操作需求 | 使用工具 | 说明 |
|---------|---------|------|
| 查看已有透视表 | `+pivot-list` | 获取透视表的结构、数据源和配置 |
| 创建/更新/删除透视表 | `+pivot-{create|update|delete}` | 对透视表执行写入操作 |
典型工作流:先读取现有透视表了解配置 → 执行创建/更新/删除 → **必须再次读取验证结果**
## 行/值字段映射(创建前必做)
创建透视表前先识别用户需求中的分组维度和聚合指标,**不要搞反**
- **rows行字段** = 分组维度,即"按什么分组"。例:部门、地区、医生、产品类别
- **values值字段** = 聚合指标,即"统计什么数值"。例:销售额(聚合方式 `sum`)、订单数(聚合方式 `count`
- **columns列字段** = 交叉维度(可选),即"再按什么横向展开"。例:月份、性别
| 用户说 | rows | values | columns |
|--------|------|--------|---------|
| "按部门统计人数" | 部门 | 姓名(`summarize_by: "count"` | — |
| "按医生统计费用和结余" | 主管医生 | 费用(`"sum"`)、结余(`"sum"` | — |
| "各部门男女人数" | 部门 | 姓名(`"count"` | 性别 |
**常见配置错误(必须注意)**
- **数据源范围必须精确**:透视表的数据源范围必须包含表头行,且精确覆盖全部数据行列。范围过大(包含空行/空列)或过小(遗漏数据列)都会导致透视表结果错误
- **行列字段选择要匹配用户意图**:用户说"按商品统计金额"→ 行字段=商品,值字段=金额(`summarize_by: "sum"`)。不要把行列字段搞反
- **聚合类型要匹配**:用户说"统计数量"→ `summarize_by: "count"`"统计总额"→ `"sum"`"统计平均"→ `"average"`。完整合法值:`sum` / `count` / `average` / `max` / `min` / `product` / `countNums` / `stdDev` / `stdDevp` / `var` / `varp` / `distinct` / `median`。默认不要用 `count` 替代 `sum`
- **参数长度限制**:如果透视表配置 JSON 过长(数据源范围跨越大量行列),可能导致工具调用失败。此时应先确认数据范围的精确边界,避免传入过大的 range
- **创建后必须验证**:调用 `+pivot-list` 确认透视表结构正确
## Shortcuts
| Shortcut | Risk | 分组 |
| --- | --- | --- |
| `+pivot-list` | read | 对象 |
| `+pivot-create` | write | 对象 |
| `+pivot-update` | write | 对象 |
| `+pivot-delete` | high-risk-write | 对象 |
## Flags
### `+pivot-list`
_公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
| `--pivot-table-id` | string | optional | 按 id 过滤 |
### `+pivot-create`
_公共URL/token无 sheet 定位) · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
| `--properties` | string + File + Stdin复合 JSON | required | JSON{"rows":[...],"columns":[...],"values":[...],"filters":[...],"show_row_grand_total":true,"show_col_grand_total":true}(数据源走 --source不要再放进 properties.source |
| `--target-position` | string | optional | 透视表落点子表内的起始 cellA1 格式,如 `A1`),映射到顶层 `target_position`,默认 `A1`(值为 A1 时不下发)。它与 `--range` 都表达落点但落在不同 wire 字段,避免两者同时给冲突值 |
| `--target-sheet-id` | string | xor | 透视表落点目标子表的 reference_id`--target-sheet-name` 互斥,优先于 --target-sheet-name都不传时自动新建一张子表放置透视表——推荐。与数据源 sheet 区分:数据源 sheet 写在 --source 的 A1 引用里(带 sheet 前缀,形如 `'Sheet1'!A1:D100`)。 |
| `--target-sheet-name` | string | xor | 透视表落点目标子表的名称(与 `--target-sheet-id` 互斥;都不传时自动新建一张子表放置透视表——推荐)。与数据源 sheet 区分:数据源 sheet 写在 --source 的 A1 引用里(带 sheet 前缀,形如 `'Sheet1'!A1:D100`)。 |
| `--source` | string | required | 透视表源数据区域A1 表示法,格式 `'SheetName'!StartCell:EndCell`,如 `'Sheet1'!A1:D100` |
| `--range` | string | optional | 透视表左上角放置位置A1 单值,如 `F1`,仅 create 生效),映射到 `properties.range`;省略时放在落点子表(默认新建子表)的左上角。它与 `--target-position` 都表达落点但落在不同 wire 字段,避免两者同时给冲突值 |
### `+pivot-update`
_公共四件套 · 系统:`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
| `--pivot-table-id` | string | required | 目标透视表 id |
| `--properties` | string + File + Stdin复合 JSON | required | 完整或足够完整的配置(先 `+pivot-list --pivot-table-id <id>` 回读再 patch |
### `+pivot-delete`
_公共四件套 · 系统:`--yes`、`--dry-run`_
| Flag | Type | 必填 | 说明 |
| --- | --- | --- | --- |
| `--pivot-table-id` | string | required | 目标透视表 id |
## Schemas
> 复合 JSON flag 字段速查(只列顶层 + 一层嵌套)。深层结构看下方 `## Examples`,或用 `--print-schema` 读完整 JSON Schema用法见 SKILL.md「公共 flag 速查」与「Agent 使用提示」)。
### `+pivot-create` `--properties` / `+pivot-update` `--properties`
_创建/更新的透视表属性_
**顶层字段**
- `range` (string?) — 放置透视表的左上角单元格 A1 地址(例如:'F1')(仅 create 时有效) — ⚠️ 已拎为独立 flag `--range`,请勿在此 JSON 内重复填写(同名以独立 flag 为准)
- `source` (string?) — 源数据区域地址,格式为 'SheetName!StartCell:EndCell'(例如:'Sheet1!A1:D100' — ⚠️ 已拎为独立 flag `--source`,请勿在此 JSON 内重复填写(同名以独立 flag 为准)
- `rows` (array<object>?) — 纵向分组字段(行字段) each: { field: string, display_name?: string, sort?: object, filter?: object, condition_filter?: object, …共 6 项 }
- `columns` (array<object>?) — 横向分组字段(列字段) each: { field: string, display_name?: string, sort?: object, filter?: object, condition_filter?: object, …共 6 项 }
- `filters` (array<object>?) — 筛选区域字段(页字段) each: { field: string, display_name?: string, filter?: object, condition_filter?: object, group?: object }
- `values` (array<object>?) — 要汇总的字段(至少需要 1 个) each: { field: string, display_name?: string, summarize_by?: enum, show_data_as?: enum, base_field?: string }
- `auto_fit_col` (boolean?) — 是否自动调整列宽以适应内容
- `show_row_grand_total` (boolean?) — 是否显示行总计(默认 true
- `show_col_grand_total` (boolean?) — 是否显示列总计(默认 true
- `show_subtotals` (boolean?) — 是否显示分类小计(默认 true应用于所有字段
- `repeat_row_labels` (boolean?) — 是否显示重复项标签
- `calculated_fields` (array<object>?) — 计算字段列表 each: { name: string, formula: string, summarize_by?: enum }
- `collapse` (object?) — 行字段展开/折叠状态:字段名 -> 要折叠的项目列表
## Examples
公共四件套:所有 shortcut 顶部排列 `--url` / `--spreadsheet-token` / `--sheet-id` / `--sheet-name`,其中 `--sheet-id` / `--sheet-name``+pivot-update` / `+pivot-delete` / `+pivot-list` 上是公共四件套语义(定位透视表所在 sheetXOR 必传一个)。
**`+pivot-create` 例外**placement 选择器用 `--target-sheet-id` / `--target-sheet-name`XOR两个都不传时后端自动新建子表存放产物强烈推荐绝不碰源数据。数据源 sheet 写在 `--source``'SheetName'!Range` 里,不靠 sheet 选择器 flag。
### `+pivot-list`
```bash
lark-cli sheets +pivot-list --url "..." --sheet-id "$SID"
```
### `+pivot-create`
> 数据源 `--source` 必须从表头行开始;空行 / 汇总行会被当作数据参与聚合,需提前用 `+csv-get` 确认起止边界。`--source` 和 `--range` 是独立 flag不要再放 `--properties``rows` / `columns` / `values` 等数组字段走 `--properties`。
>
> **先理清 `+pivot-create` 上 4 个位置类入参(语义不同,别混)**
> - `--source`**必填****源数据**区域,须自带 `Sheet!` 前缀(如 `'Sheet1'!A1:D100`sheet 名按 A1 标准单引号包裹)。源 sheet 的名字在 `--source` 字符串里,**不**通过单独 flag 传。
> - `--target-sheet-id` / `--target-sheet-name`**透视表的落点 sheet**(即产物放哪张子表)。两个互斥(最多传一个),都不传时后端自动新建子表存放产物(强烈推荐)。
> - `--target-position`可选A1 表示法,默认 `A1`):落点 sheet 内的起始 cell映射到顶层 `target_position`。
> - `--range`可选A1 单值,仅 create 生效):跟 `--target-position` 表达同一意图但映射到 `properties.range`**两者不要同时给**。
>
> **落点 3 种策略(互斥,选其一)**
> 1. **默认(强烈推荐)**`--target-sheet-id` / `--target-sheet-name` / `--target-position` / `--range` **全都不传** → 服务端**自动新建子表**存放产物,绝不碰任何已有数据。
> 2. **放进指定的已有子表**:传 `--target-sheet-id <落点子表 id>`(或 `--target-sheet-name`),可选 `--target-position <子表内起点 cell>`。⚠️ **若落点子表就是源数据所在的 sheet**,必须配 `--target-position` 或 `--range` 指向源数据范围**之外**的位置,否则产物默认从 A1 起会盖在源数据上。
> 3. **`--range`**:跟策略 2 等价(同样需要 `--target-sheet-id` / `--target-sheet-name` 指定落点子表,不然落到自动新建子表),只是用 `properties.range` 那条 wire 路径表达位置。同样的覆盖风险,同样需要避开源数据范围。
>
> 一般用策略 1默认新建子表即可零覆盖风险无需任何 `--target-*` / `--range` flag。
```bash
# 策略 1强烈推荐不传任何落点 flag → 后端自动新建子表,零覆盖风险
lark-cli sheets +pivot-create --url "..." \
--source "'Sheet1'!A1:D100" --properties @pivot.json
# 策略 2落进指定的已有目标子表注意目标 sheet ≠ 源 sheet否则要配 --target-position 避开源数据)
lark-cli sheets +pivot-create --url "..." \
--source "'Sheet1'!A1:D100" --target-sheet-id "$DEST_SID" --target-position "A1" --properties @pivot.json
```
### `+pivot-update`
> 不允许改 `--source` / `--range`(透视表创建后位置/数据源固定);只能用 `--properties` 改 rows / columns / values / filters 等。先 `+pivot-list --pivot-table-id <id>` 回读再 patch避免漏字段。
### `+pivot-delete`
```bash
lark-cli sheets +pivot-delete --url "..." --sheet-id "$SID" --pivot-table-id "$PID" --yes
```
### Validate / DryRun / Execute 约束
- `Validate``--url` / `--spreadsheet-token` XOR 必填;`+pivot-{update,delete,list}``--sheet-id` / `--sheet-name` XOR 必填一个;`+pivot-create` 例外(用 `--target-sheet-id` / `--target-sheet-name` 表达落点,两个都可空时触发 backend auto-create 子表,两个都给则报 mutually exclusive`+pivot-create``--source` 必填且必须含表头行;`--properties``rows` / `columns` / `values` 至少非空之一;`+pivot-delete` 强制 `--yes``--dry-run`
- `DryRun`:写操作输出"将要 POST/PATCH/DELETE 的 pivot 请求模板"+ 预估输出尺寸(行数 × 列数)。
- `Execute`:写后不自动回读;如需确认,自行调用 `+pivot-list --pivot-table-id <id>` 并用 `+csv-get` 抽样读透视产物核对输出尺寸 + 总计行位置。
> ⚠️ pivot 输出包含总计 / 小计行;后续 chart 引用 pivot 时,`snapshot.data.refs` 必须排除这些行(见 `lark-sheets-chart` 的「⚠️ chart 数据源引用 pivot 时必须排除总计行」段)。