Files
su-planning-office/skills/tencent-survey/references/update_logic.md
T

236 lines
8.8 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.
# update_logic 工具参考
## 概述
更新问卷的自定义逻辑设置(DSL 代码)。可通过 `get_survey` 返回的 `survey_dsl` 字段获取当前逻辑代码,修改后整体传入。传入空字符串可清空所有逻辑。
## 参数
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| `survey_id` | number | **是** | 问卷 ID |
| `dsl` | string | **是** | 问卷自定义逻辑代码(DSL 脚本语法) |
> **重要**:`dsl` 中引用题目和选项时需使用反引号包裹的 ID 格式(如 `` `q-1-abcd::o-100-ABCD` ``),ID 可从 `get_survey` 返回的题目和选项信息中获取。
## 返回值
### 成功响应
```json
{
"survey_id": 716128,
"result": "success"
}
```
### 失败响应
```json
{
"survey_id": 716128,
"result": "failed",
"error": "invalid_dsl_syntax: ..."
}
```
### 字段说明
| 字段 | 类型 | 说明 |
|------|------|------|
| `survey_id` | number | 问卷 ID |
| `result` | string | `"success"` 表示成功,`"failed"` 表示失败 |
| `error` | string | 仅失败时返回,错误描述信息 |
## DSL 语法说明
自定义逻辑使用 DSL(Domain-Specific Language)脚本语法。多条规则用换行分隔。
> 📖 完整语法文档:https://wj.qq.com/docs/dsl/grammar
### 引用格式
在通过 MCP 工具编写 DSL 时,题目和选项 ID 需要使用**反引号包裹**:
| 元素 | 格式 | 示例 |
|------|------|------|
| 题目 | `` `q-1-xxxx` `` | `` `q-1-abcd` `` |
| 选项 | `` `q-1-xxxx::o-100-ABCD` `` | `` `q-1-abcd::o-100-EFGH` `` |
| 矩阵子问题 | `` `q-1-xxxx::s-200-IJKL` `` | `` `q-1-abcd::s-200-IJKL` `` |
| 填空项 | `` `q-1-xxxx::b-300-MNOP` `` | `` `q-1-abcd::b-300-MNOP` `` |
> **注意**:ID 值必须从 `get_survey` 返回的数据中获取,不能自行构造。
### 条件操作符
| 操作符 | 说明 | 示例 |
|--------|------|------|
| `and` | 逻辑与 | `if Q1A1 and Q2A2 then show Q3` |
| `or` | 逻辑或 | `if Q1A1 or Q1A2 then show Q2` |
| `not` | 逻辑非 | `if Q1 and not Q1A3 then show Q2` |
| `()` | 分组 | `if (Q1A1 or Q1A2) and Q2A1 then show Q3` |
| `>` `>=` `==` `<` `<=` | 比较 | `if Q1 > 5 then show Q2` |
| `+` `-` `*` `/` | 算数运算 | `if Q1 + Q2 > 10 then show Q3` |
### 行为控制语句
| 语句类型 | 语法格式 | 说明 |
|---------|---------|------|
| **条件显示** | `if <条件> then show <目标>` | 满足条件时显示题目或选项 |
| **条件隐藏** | `if <条件> then hide <目标>` | 满足条件时隐藏题目或选项 |
| **直接隐藏** | `hide <目标>` | 直接隐藏题目或选项(无条件) |
| **连线跳转** | `if <条件> then branch from <题目> to <目标>` | 满足条件时从某题跳转到指定题目或 `END` |
| **内容替换** | `replace "<文本>" in <题目> title with <来源>` | 将题目标题中的指定文本替换为另一题的回答 |
| **随机排序** | `shuffle <范围>` | 对题目或选项进行随机排序 |
| **随机抽取** | `random show <数量> from <范围>` | 从题目或选项中随机抽取指定数量显示 |
| **自动圈选** | `set <选项>` | 自动选中指定选项 |
| **自动填充** | `set <题目> = <来源>` | 自动填充文本题内容 |
### 特殊关键字
| 关键字 | 说明 | 示例 |
|--------|------|------|
| `END` | 结束页,用于跳转到问卷结尾 | `branch from Q1 to END` |
| `len` | 答案个数 | `if len Q1 > 2 then show Q3` |
| `index` | 答案排在第几位 | `if index Q1A1 == 1 then show Q2` |
| `RANDBETWEEN(min, max)` | 随机生成整数 | `if RANDBETWEEN(1, 10) > 5 then show Q2` |
| `LANG()` | 获取答题者语言 | `if LANG() == "zhs" then show Q1` |
| `PARAMS("key")` | 获取自定义参数 | `if PARAMS("source") == "wechat" then show Q2` |
| `#` | 注释 | `# 这是注释,不会被执行` |
### 范围表示
| 格式 | 说明 | 示例 |
|------|------|------|
| `Q1~3` | 题目 Q1 到 Q3 | `shuffle Q1~3` |
| `Q1A1~4` | 题目 Q1 的选项 A1 到 A4 | `shuffle Q1A1~4` |
| `Q1,Q3,Q5` | 不连续的题目 | `random show 1 from Q1,Q3,Q5` |
> 当连续 3 个以上序号时,系统会自动合并为 `~` 格式。
### weight 权重
`random show` 支持设置权重:
```
random show 1 from Q1~3 weight by 1:1:2
```
表示 Q3 被抽取的概率是 Q1、Q2 的两倍。
## 调用示例
### 典型工作流
```
# 1. 先获取问卷详情,确认题目和选项 ID
get_survey(survey_id=716128)
# 返回中查看 survey_dsl.code 获取当前逻辑代码
# 从 pages → questions → options 中获取题目和选项的 ID
# 2. 编写并更新逻辑
update_logic(survey_id=716128, dsl="if `q-1-abcd::o-100-EFGH` then show `q-1-ijkl`")
```
### 条件显示逻辑
```
# 选择了第1题的第1个选项时,显示第2题
update_logic(survey_id=716128, dsl="if `q-1-abcd::o-100-EFGH` then show `q-1-ijkl`")
```
### 多条件组合
```
# 第1题选了A 且 第2题选了B 时,显示第3题
update_logic(survey_id=716128, dsl="if `q-1-abcd::o-100-EFGH` and `q-1-ijkl::o-200-MNOP` then show `q-1-qrst`")
```
### 连线跳转(甄别题)
```
# 选择了第1题某选项时,跳转到问卷结束
update_logic(survey_id=716128, dsl="if `q-1-abcd::o-100-EFGH` then branch from `q-1-abcd` to END")
```
### 内容替换
```
# 将第3题标题中的"XXX"替换为第1题的回答
update_logic(survey_id=716128, dsl="replace \"XXX\" in `q-1-qrst` title with `q-1-abcd`")
```
### 随机排序与随机抽取
```
# 随机排序第1题的选项1~4
update_logic(survey_id=716128, dsl="shuffle `q-1-abcd::o-100-A`~`q-1-abcd::o-100-D`")
# 从题目1~3中随机抽取1道显示
update_logic(survey_id=716128, dsl="random show 1 from `q-1-abcd`~`q-1-qrst`")
```
### 多条规则组合
```
# 多条规则用换行分隔
update_logic(survey_id=716128, dsl="if `q-1-abcd::o-100-EFGH` then show `q-1-ijkl`\nif `q-1-abcd::o-100-MNOP` then show `q-1-qrst`\nreplace \"XXX\" in `q-1-uvwx` title with `q-1-abcd`")
```
### 清空所有逻辑
```
update_logic(survey_id=716128, dsl="")
```
### mcporter 调用
```bash
# 设置条件显示逻辑
mcporter call tencent-survey.update_logic --args '{"survey_id": 716128, "dsl": "if `q-1-abcd::o-100-EFGH` then show `q-1-ijkl`"}'
# 清空所有逻辑
mcporter call tencent-survey.update_logic --args '{"survey_id": 716128, "dsl": ""}'
```
## 权限要求
调用此接口需要满足以下权限条件(逐级校验):
| 校验层 | 说明 |
|--------|------|
| `WithSurveyClaims` | 问卷归属校验:问卷必须属于当前 Token 绑定的团队 |
| `WithSurveyEditorClaims` | 编辑权限校验:当前用户需具有该问卷的编辑权限 |
| `WithSurveyEditableClaims` | 可编辑状态校验:问卷必须处于可编辑状态(如草稿状态) |
## 错误码
| error.type | 错误描述 | 解决方案 |
|------------|---------|---------|
| `invalid_dsl_syntax` | DSL 语法错误 | 检查 DSL 代码语法是否正确,参考语法文档 |
| `invalid_reference` | 引用的题目/选项 ID 不存在 | 确认 ID 从 get_survey 返回数据中获取 |
| `claim_error` | 权限校验错误 | 问卷不属于当前 Token 绑定的团队,或无编辑权限 |
| `survey_not_editable` | 问卷不可编辑 | 问卷可能正在回收中,需先暂停回收 |
| `invalid_argument` | 参数校验不通过 | 检查 survey_id、dsl 是否正确 |
## 注意事项
1. **先获取再更新**:必须先调用 `get_survey` 获取问卷详情,从返回数据中获取正确的题目 ID 和选项 ID
2. **整体覆盖**:`dsl` 参数为问卷的完整逻辑代码,每次调用会覆盖所有已有逻辑。如需追加规则,需先获取当前 `survey_dsl.code`,在其基础上修改后整体传入
3. **非幂等操作**:每次调用都会覆盖原有逻辑配置
4. **ID 使用反引号**:通过 MCP 工具编写 DSL 时,题目和选项 ID 需使用反引号包裹(如 `` `q-1-abcd::o-100-EFGH` ``)
5. **多条规则换行分隔**:在 JSON 参数中,多条规则之间使用 `\n` 分隔
6. **清空逻辑**:传入空字符串(`""`)可清空所有自定义逻辑
7. **问卷状态要求**:问卷必须处于可编辑状态,正在回收中的问卷需先暂停才能编辑
8. **与基础逻辑共存**:自定义逻辑与基础逻辑可同时设置,执行顺序为先执行基础逻辑、再执行自定义逻辑
9. **付费功能**:自定义逻辑为付费高级功能。如调用时返回 `paid_function_trial_no_permission` 错误,说明当前团队未购买该功能权限,需引导用户前往[腾讯问卷购买页](https://wj.qq.com/pricing)进行付费升级(升级为付费版本)后再使用
## Annotations(工具注解)
| 注解 | 值 | 说明 |
|------|---|------|
| `readOnlyHint` | false | 非只读操作,会修改问卷逻辑配置 |
| `destructiveHint` | false | 非破坏性操作(更新而非删除) |
| `idempotentHint` | false | **非幂等**,每次调用都覆盖逻辑配置 |
| `openWorldHint` | false | 内部调用 |