feat:simplify quick-ref

This commit is contained in:
zhanghuanxu
2026-07-07 19:22:30 +08:00
parent 0db6fe4b4d
commit ba20f354ed
3 changed files with 0 additions and 489 deletions

View File

@@ -1,261 +0,0 @@
# 完整操作示例
本文档提供与 CLI schema 一致的调用示例XML 内容均遵循 [slides_xml_schema_definition.xml](slides_xml_schema_definition.xml)。
> **重要**:创建 PPT 请优先使用 `slides +create`;实际页面内容请使用 `xml_presentation.slide.create` 逐页添加。
## 目录
- [示例 1: 使用 Shortcut 创建空白演示文稿](#示例-1-使用-shortcut-创建空白演示文稿)
- [示例 2: 创建后添加第一页](#示例-2-创建后添加第一页)
- [示例 3: 读取 XML 内容](#示例-3-读取-xml-内容)
- [示例 4: 在指定页面前插入新幻灯片](#示例-4-在指定页面前插入新幻灯片)
- [示例 5: 删除幻灯片](#示例-5-删除幻灯片)
- [示例 6: 从文件读取 XML 后添加页面](#示例-6-从文件读取-xml-后添加页面)
- [示例 7: +replace-slide + block_insert 给已有页加图](#示例-7-replace-slide--block_insert-给已有页加图)
- [示例 8: +replace-slide + block_replace 替换一个块](#示例-8-replace-slide--block_replace-替换一个块)
## 示例 1: 使用 Shortcut 创建空白演示文稿
```bash
lark-cli slides +create --title "项目汇报"
```
预期返回结构:
```json
{
"data": {
"xml_presentation_id": "slides_example_presentation_id",
"title": "项目汇报",
"revision_id": 1
}
}
```
## 示例 2: 创建后添加第一页
```bash
PRESENTATION_ID=$(lark-cli slides +create --title "季度复盘" | jq -r '.data.xml_presentation_id')
lark-cli slides xml_presentation.slide create --as user --params "{\"xml_presentation_id\":\"$PRESENTATION_ID\"}" --data '{
"slide": {
"content": "<slide xmlns=\"http://www.larkoffice.com/sml/2.0\"><style><fill><fillColor color=\"rgb(245, 245, 245)\"/></fill></style><data><shape type=\"text\" topLeftX=\"80\" topLeftY=\"72\" width=\"760\" height=\"90\"><content textType=\"title\"><p>2024 Q3 季度复盘</p></content></shape><shape type=\"text\" topLeftX=\"80\" topLeftY=\"190\" width=\"520\" height=\"220\"><content textType=\"body\"><p>关键结论</p><ul><li><p>收入增长 30%</p></li><li><p>重点项目全部上线</p></li><li><p>用户满意度持续提升</p></li></ul></content></shape><shape type=\"rect\" topLeftX=\"660\" topLeftY=\"180\" width=\"180\" height=\"140\"><fill><fillColor color=\"rgba(100, 149, 237, 0.25)\"/></fill><border color=\"rgb(100, 149, 237)\" width=\"2\"/></shape></data><note><content textType=\"body\"><p>讲述时先给结论,再补充数据。</p></content></note></slide>"
}
}'
```
## 示例 3: 读取 XML 内容
```bash
lark-cli slides xml_presentations get --as user --params '{
"xml_presentation_id": "slides_example_presentation_id"
}'
```
提取 XML 内容:
```bash
lark-cli slides xml_presentations get --as user --params '{
"xml_presentation_id": "slides_example_presentation_id"
}' | jq -r '.data.xml_presentation.content'
```
预期返回结构:
```json
{
"code": 0,
"data": {
"xml_presentation": {
"presentation_id": "slides_example_presentation_id",
"revision_id": 3,
"content": "<presentation xmlns=\"http://www.larkoffice.com/sml/2.0\" height=\"540\" width=\"960\">...</presentation>"
}
},
"msg": "success"
}
```
## 示例 4: 在指定页面前插入新幻灯片
```bash
lark-cli slides xml_presentation.slide create --as user --params '{
"xml_presentation_id": "slides_example_presentation_id"
}' --data '{
"slide": {
"content": "<slide xmlns=\"http://www.larkoffice.com/sml/2.0\"><data><shape type=\"text\" topLeftX=\"80\" topLeftY=\"80\" width=\"800\" height=\"120\"><content textType=\"title\"><p>新增页面</p></content></shape><shape type=\"text\" topLeftX=\"80\" topLeftY=\"200\" width=\"800\" height=\"180\"><content textType=\"body\"><p>这是新增页面的正文。</p></content></shape></data></slide>"
},
"before_slide_id": "sld_before_target"
}'
```
预期返回结构:
```json
{
"code": 0,
"data": {
"slide_id": "slide_example_id",
"revision_id": 100
},
"msg": "success"
}
```
## 示例 5: 删除幻灯片
```bash
lark-cli slides xml_presentation.slide delete --as user --params '{
"xml_presentation_id": "slides_example_presentation_id",
"slide_id": "slide_example_id"
}'
```
预期返回结构:
```json
{
"code": 0,
"data": {
"revision_id": 101
},
"msg": "success"
}
```
## 示例 6: 从文件读取 XML 后添加页面
先准备 `slide.xml`
```xml
<slide xmlns="http://www.larkoffice.com/sml/2.0">
<data>
<shape type="text" topLeftX="80" topLeftY="80" width="800" height="120">
<content textType="title">
<p>从文件加载</p>
</content>
</shape>
</data>
</slide>
```
先创建演示文稿:
```bash
PRESENTATION_ID=$(lark-cli slides +create --title "从文件添加页面" | jq -r '.data.xml_presentation_id')
```
再用 `jq` 组装请求体,从文件添加页面:
```bash
lark-cli slides xml_presentation.slide create --as user \
--params "{\"xml_presentation_id\":\"$PRESENTATION_ID\"}" \
--data "$(jq -n --arg content "$(cat slide.xml)" '{slide:{content:$content}}')"
```
## 示例 7: +replace-slide + block_insert 给已有页加图
只想在已有页上加一张图、不动其他元素——走 shortcut `+replace-slide``block_insert` 追加到页末(或用 `insert_before_block_id` 指定位置)。
```bash
PID="slides_example_presentation_id"
SID="slide_example_id"
# 1. 上传图片拿 file_token
TOKEN=$(lark-cli slides +media-upload --file ./pic.png --presentation "$PID" --as user \
| jq -r '.data.file_token')
# 2. block_insert 到页面末尾(省略 insert_before_block_id
# 注:<img .../> 是自闭合标签CLI 不会展开(只有 <shape/> 会被补 <content/>
lark-cli slides +replace-slide --as user \
--presentation "$PID" --slide-id "$SID" \
--parts "$(jq -n --arg token "$TOKEN" \
'[{action:"block_insert",insertion:("<img src=\""+$token+"\" topLeftX=\"500\" topLeftY=\"100\" width=\"200\" height=\"150\"/>")}]')"
```
预期返回:
```json
{
"ok": true,
"data": {
"xml_presentation_id": "slides_example_presentation_id",
"slide_id": "slide_example_id",
"parts_count": 1,
"revision_id": 102
}
}
```
## 示例 8: +replace-slide + block_replace 替换一个块
已知某块的 3 位 short element ID`slide.get` 返回 XML 里读),整块换掉。`replacement` 根元素的 `id` 会由 CLI 自动注入为 `block_id`,无需手写;若写了 `<shape/>` 自闭合形式CLI 也会自动补 `<content/>`
```bash
lark-cli slides +replace-slide --as user \
--presentation slides_example_presentation_id \
--slide-id slide_example_id \
--parts '[
{
"action": "block_replace",
"block_id": "bab",
"replacement": "<shape type=\"text\" topLeftX=\"80\" topLeftY=\"80\" width=\"800\" height=\"120\"><content textType=\"title\"><p>新标题</p></content></shape>"
}
]'
# CLI 实际发送的 replacement 根元素会带 id="bab",即使手写时省略了
```
失败时3350001 错误CLI 在 error 字段中给出 hint
```json
{
"ok": false,
"error": {
"type": "api",
"code": 3350001,
"message": "API error: [3350001] invalid param",
"hint": "common causes: (1) block_id not found in current slide ..."
}
}
```
整批作为原子事务,任一 part 失败则整批不生效;按 `failed_part_index` 定位修正后重发。
## 常见处理技巧
### 获取最新 revision_id
```bash
lark-cli slides xml_presentations get --as user --params '{
"xml_presentation_id": "slides_example_presentation_id"
}' | jq '.data.xml_presentation.revision_id'
```
### 批量插入多页
```bash
#!/bin/bash
PRESENTATION_ID="slides_example_presentation_id"
slides=(
'<slide xmlns="http://www.larkoffice.com/sml/2.0"><data><shape type="text" topLeftX="80" topLeftY="80" width="800" height="120"><content textType="title"><p>页面 1</p></content></shape></data></slide>'
'<slide xmlns="http://www.larkoffice.com/sml/2.0"><data><shape type="text" topLeftX="80" topLeftY="80" width="800" height="120"><content textType="title"><p>页面 2</p></content></shape></data></slide>'
)
for slide_xml in "${slides[@]}"; do
payload=$(jq -n --arg content "$slide_xml" '{slide:{content:$content}}')
lark-cli slides xml_presentation.slide create --as user --params "{\"xml_presentation_id\":\"$PRESENTATION_ID\"}" --data "$payload"
done
```
### 本地校验 XML 基本语法
```bash
xmllint --noout presentation.xml
```
### 真实示例
- [slides_demo.xml](slides_demo.xml) 提供了更完整的页面示例,包含 `theme`、渐变填充、图片、图标和备注内容。

View File

@@ -1,226 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<presentation xmlns="http://www.larkoffice.com/sml/2.0" height="540" width="960">
<title>制造端智能升级</title>
<theme>
<textStyles>
<headline fontColor="rgb(255,255,255)" fontFamily="思源黑体" fontSize="36"/>
<sub-headline fontColor="rgb(229,231,235)" fontFamily="思源黑体" fontSize="20"/>
<body fontColor="rgb(229,231,235)" fontFamily="思源黑体" fontSize="16"/>
</textStyles>
</theme>
<slide>
<style>
<fill>
<fillColor color="linear-gradient(180deg, rgb(47, 79, 79) 0%, rgb(26, 26, 26) 100%)"/>
</fill>
</style>
<data>
<shape height="36" rotation="0" topLeftX="48" topLeftY="40" type="text" width="300">
<content>
<p>
<strong>
<span color="rgb(255, 215, 0)" fontFamily="黑体" fontSize="28">时代背景</span>
</strong>
</p>
</content>
</shape>
<shape height="200" rotation="0" topLeftX="48" topLeftY="85" type="rect" width="864">
<fill>
<fillColor color="rgba(0,0,0,0.2)"/>
</fill>
</shape>
<img alpha="0.4" alt="十月革命场景" height="180" rotation="0" src="https://example.com/images/scene-1.png" topLeftX="48" topLeftY="95" width="288">
<crop type="rect"/>
</img>
<img alpha="0.4" alt="列宁演讲油画" height="180" rotation="0" src="https://example.com/images/scene-2.png" topLeftX="336" topLeftY="95" width="288">
<crop type="rect"/>
</img>
<img alpha="0.4" alt="十月革命战斗场面" height="180" rotation="0" src="https://example.com/images/scene-3.png" topLeftX="624" topLeftY="95" width="288">
<crop type="rect"/>
</img>
<shape height="2" rotation="0" topLeftX="90" topLeftY="180" type="rect" width="780">
<fill>
<fillColor color="rgba(255, 215, 0, 0.3)"/>
</fill>
</shape>
<shape height="10" rotation="0" topLeftX="120" topLeftY="176" type="ellipse" width="10">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
<border color="rgb(255, 215, 0)" width="1"/>
</shape>
<shape height="24" rotation="0" topLeftX="60" topLeftY="140" type="text" width="200">
<content>
<p textAlign="center">
<strong>
<span color="rgb(255, 215, 0)" fontFamily="黑体" fontSize="20">1917</span>
</strong>
</p>
</content>
</shape>
<shape height="22" rotation="0" topLeftX="60" topLeftY="200" type="text" width="200">
<content>
<p textAlign="center">
<span color="rgb(230, 230, 230)" fontFamily="宋体" fontSize="16">十月革命</span>
</p>
</content>
</shape>
<shape height="40" rotation="0" topLeftX="60" topLeftY="225" type="text" width="200">
<content verticalAlign="top">
<p textAlign="center">
<span color="rgb(156, 163, 175)" fontSize="12">沙皇专制终结,苏维埃政权建立</span>
</p>
</content>
</shape>
<shape height="10" rotation="0" topLeftX="475" topLeftY="176" type="ellipse" width="10">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
<border color="rgb(255, 215, 0)" width="1"/>
</shape>
<shape height="24" rotation="0" topLeftX="380" topLeftY="140" type="text" width="200">
<content>
<p textAlign="center">
<strong>
<span color="rgb(255, 215, 0)" fontFamily="黑体" fontSize="20">1920s</span>
</strong>
</p>
</content>
</shape>
<shape height="22" rotation="0" topLeftX="380" topLeftY="200" type="text" width="200">
<content>
<p textAlign="center">
<span color="rgb(230, 230, 230)" fontFamily="宋体" fontSize="16">国内战争</span>
</p>
</content>
</shape>
<shape height="40" rotation="0" topLeftX="380" topLeftY="225" type="text" width="200">
<content verticalAlign="top">
<p textAlign="center">
<span color="rgb(156, 163, 175)" fontSize="12">革命与反革命的残酷斗争</span>
</p>
</content>
</shape>
<shape height="10" rotation="0" topLeftX="830" topLeftY="176" type="ellipse" width="10">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
<border color="rgb(255, 215, 0)" width="1"/>
</shape>
<shape height="24" rotation="0" topLeftX="740" topLeftY="140" type="text" width="200">
<content>
<p textAlign="center">
<strong>
<span color="rgb(255, 215, 0)" fontFamily="黑体" fontSize="20">1930s</span>
</strong>
</p>
</content>
</shape>
<shape height="22" rotation="0" topLeftX="740" topLeftY="200" type="text" width="200">
<content>
<p textAlign="center">
<span color="rgb(230, 230, 230)" fontFamily="宋体" fontSize="16">社会主义建设</span>
</p>
</content>
</shape>
<shape height="40" rotation="0" topLeftX="740" topLeftY="225" type="text" width="200">
<content verticalAlign="top">
<p textAlign="center">
<span color="rgb(156, 163, 175)" fontSize="12">新经济政策与工业化探索</span>
</p>
</content>
</shape>
<shape height="1" rotation="0" topLeftX="48" topLeftY="300" type="rect" width="864">
<fill>
<fillColor color="rgba(255, 215, 0, 0.2)"/>
</fill>
</shape>
<shape height="24" rotation="0" topLeftX="48" topLeftY="320" type="text" width="280">
<content>
<p>
<span color="rgb(230, 230, 230)" fontFamily="宋体" fontSize="18">作者:奥斯特洛夫斯基</span>
</p>
</content>
</shape>
<icon height="16" iconType="iconpark/Peoples/user.svg" topLeftX="52" topLeftY="360" width="16">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
</icon>
<shape height="20" topLeftX="76" topLeftY="358" type="text" width="260">
<content verticalAlign="middle">
<p>
<span color="rgb(209, 213, 219)" fontSize="13">工人家庭出身,投身革命浪潮</span>
</p>
</content>
</shape>
<icon height="16" iconType="iconpark/Sports/torch.svg" topLeftX="52" topLeftY="390" width="16">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
</icon>
<shape height="20" topLeftX="76" topLeftY="388" type="text" width="260">
<content verticalAlign="middle">
<p>
<span color="rgb(209, 213, 219)" fontSize="13">战场负伤致残,生命陷入黑暗</span>
</p>
</content>
</shape>
<icon height="16" iconType="iconpark/Health/first-aid-kit.svg" topLeftX="52" topLeftY="420" width="16">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
</icon>
<shape height="20" topLeftX="76" topLeftY="418" type="text" width="260">
<content verticalAlign="middle">
<p>
<span color="rgb(209, 213, 219)" fontSize="13">全身瘫痪、双目失明</span>
</p>
</content>
</shape>
<icon height="16" iconType="iconpark/Edit/edit.svg" topLeftX="52" topLeftY="450" width="16">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
</icon>
<shape height="20" topLeftX="76" topLeftY="448" type="text" width="260">
<content verticalAlign="middle">
<p>
<span color="rgb(209, 213, 219)" fontSize="13">以文学为武器,口述完成创作</span>
</p>
</content>
</shape>
<img alt="奥斯特洛夫斯基青年时期" height="213" rotation="0" src="https://example.com/images/ostrovsky.png" topLeftX="360" topLeftY="320" width="160">
<border color="rgba(255, 215, 0, 0.5)" width="2"/>
<crop type="rect"/>
</img>
<shape height="24" rotation="0" topLeftX="552" topLeftY="320" type="text" width="360">
<content>
<p>
<span color="rgb(230, 230, 230)" fontFamily="宋体" fontSize="18">创作动机</span>
</p>
</content>
</shape>
<shape height="16" rotation="0" topLeftX="552" topLeftY="350" type="rect" width="2">
<fill>
<fillColor color="rgb(196, 30, 58)"/>
</fill>
</shape>
<shape height="120" rotation="0" topLeftX="562" topLeftY="350" type="text" width="350">
<content lineSpacing="multiple:1.6" verticalAlign="top">
<p>
<span color="rgb(209, 213, 219)" fontSize="13">在双目失明、全身瘫痪的逆境中,奥斯特洛夫斯基以自身经历为蓝本,用顽强的意志口述完成了这部不朽巨著。他将文学创作视为生命的延续和战斗的武器,旨在通过保尔·柯察金的形象,向青年一代传递坚不可摧的革命信念和超越个人痛苦的崇高人生价值观。</span>
</p>
</content>
</shape>
</data>
<note>
<content>
<p>各位好,这一页将我们带回《钢铁是怎样炼成的》这部巨著诞生的波澜壮阔的时代。</p>
<p>上半部分展示了从1917年十月革命到1930年代苏联社会主义建设的宏大历史画卷。这是一个充满剧烈社会变革和残酷斗争的年代也是英雄主义和理想主义精神熊熊燃烧的年代。正是这样的背景孕育了小说的灵魂。</p>
<p>下半部分,我们聚焦于作者奥斯特洛夫斯基的个人经历。他的一生,本身就是一部比小说更震撼人心的传奇。从投身革命的青年,到因伤致残的战士,再到与命运抗争的文学巨匠。他的创作动机源于自身不屈的战斗精神,他希望用保尔的故事激励后人,在任何困境中都不要放弃理想,要将有限的生命投入到无限的为人类解放而斗争的事业中去。</p>
<p>通过了解这段历史和作者的生平,我们能更深刻地理解《钢铁是怎样炼成的》这部作品的伟大之处。</p>
</content>
</note>
</slide>
</presentation>

View File

@@ -435,8 +435,6 @@ Mermaid 模式:内容用 `<![CDATA[...]]>` 包裹,避免 `[`、`>`、`-->`
## 详细参考
- [slides_xml_schema_definition.xml](slides_xml_schema_definition.xml)
- [examples.md](examples.md)
- [slides_demo.xml](slides_demo.xml)
- [slides_chart_demo.xml](slides_chart_demo.xml)
## Schema 版本信息