云捷电商工具箱 开发者文档 · 从零到上架的完整流程 下载开发包 下载 Markdown 返回官网
一、开始之前 这套东西是什么 要准备什么 下载并安装 Trae
二、三步上手 第 1 步:拿开发包 第 2 步:用 Trae 打开 第 3 步:关联目录调试
三、怎么开发 目录结构与入口 业务代码骨架 常用能力速查 铁律与交付前自查
四、调试与排错 改了代码怎么看效果 常见报错与坑
五、上架 打包提交审核 版本与更新开发包
六、完整流程清单 照着做一遍就能上架
七、常见问题 FAQ 接口与文件链接

这套东西是什么

先弄清三个概念,后面就不会迷路。
名词是什么谁来维护
客户端 用户装的 PC 软件(Windows)。里面能开店铺页,也能装「应用」(插件),应用跑在客户端里。 平台
应用市场 开发者把自己写的插件上架,用户在客户端的应用市场里安装、订阅、付费。 平台 + 开发者
开发包 你写插件要用的一整套东西:云捷SDK.js(唯一能力入口)+ 开发文档/skill + 模板 + 组件 + UI 资源。一个 zip、一个版本号。 平台下发(你只管用)
SDK 里已经把「抖店/抖音接口、店铺登录态、缓存、数据库、文件、定时任务、浏览器自动化、AI、签名」这些都封装好了。 你写的插件只调 SDK,不用管登录、签名、跨域,也不能直接连数据库。

要准备什么

三样东西,十分钟能齐。
  1. 一台 Windows 电脑(Windows 10 / 11 64 位)。插件开发不挑机器,办公本就行。
  2. 云捷电商工具箱客户端 + 一个开发者账号:客户端用来「本地调试」和「打包提交审核」; 开发者账号用来登录客户端的开发者中心。
  3. 代码编辑器:Trae(字节的 AI IDE,基于 VS Code 内核)。为什么用它: 开发包里自带 .trae/skills/,用 Trae 打开开发包目录后,AI 会**自动按云捷的规范**帮你写插件、 查接口、避坑,比手写快很多。用 VS Code 也能开发(只是没有这套 skill 加持)。

下载并安装 Trae

Trae 是字节跳动的 AI IDE(Windows / macOS / Linux 都有),Windows 版约 350MB。

1. 下载

  1. 浏览器打开 Trae 中国官网https://www.trae.com.cn/ (下载页:https://www.trae.com.cn/download
  2. 点右上角「下载 IDE」→ 选 Windows x64,得到 Trae CN-Setup-x64.exe
  3. 海外网络环境可用国际版:https://www.trae.ai/
只从官网下,别用第三方下载站(容易被捆东西)。系统要求:Windows 10(64 位,版本 ≥1903)或 Windows 11;内存 8GB 起(推荐 16GB)。

2. 安装

  1. 右键安装包 →「以管理员身份运行
  2. 同意协议 → 选安装路径:装到非系统盘、纯英文路径(如 D:\Trae),不要中文/空格
  3. 勾「创建桌面快捷方式」→ 安装 → 完成后启动

3. 首次启动配置

  1. 选主题、选语言(简体中文
  2. 可从 VS Code / Cursor 导入已有配置(快捷键、插件、主题)
  3. 手机号(或稀土掘金账号)登录,AI 功能才会生效
  4. 按提示「添加命令行」(可选,之后能在终端用 trae 打开项目)
装完先别急着写代码 —— 下一步是「拿到开发包并用 Trae 打开开发包目录」, 打开后 AI 就自动带上云捷插件开发规范了。

第 1 步:拿开发包

开发包 = 你插件的「起手式」,根目录就是你的工作目录。
  1. 点右上角「下载开发包」(就是 GET /api/docs/kit.zip),拿到 kit.zip
  2. 解压到一个好找、路径纯英文的目录,例如 D:\我的插件

解压后的结构(用 Trae 打开这个目录即可):

D:\开发包\                   ← 开发包目录
├── 云捷SDK.js              ← 唯一能力入口,别手写、别改名
├── SDK更新日志.md           ← 每个版本改了什么
├── 资源\                   ← vue.min.js + element-ui(本地文件,不要改用 CDN)
├── 模板\                   ← 六个现成骨架(最小插件 / 列表操作插件 / 批量任务插件 / 定时器示例 / 首页面板示例 / 搜索商品示例)
├── 组件\                   ← 可复用组件(如 SKU搜索.js)
├── .trae\skills\           ← 给 Trae 的云捷插件开发 skill(用 Trae 打开本目录即生效)
└── 参考\                   ← 分模块文档(SDK 速查 / 营销 / 商品 / 售后 / 避坑…)
规范做法:把 模板\最小插件\(或 列表操作插件 / 批量任务插件) 整个目录复制出去当你的插件目录,再改成你要的功能 —— 模板里已经带了 云捷SDK.js资源\
⚠️ 提交版本前注意:打包只打包「发布」目录,要上线的内容得放在 发布\ 里,可直接参考这一结构。
别把开发包「拆开用」:整个包是配套的(SDK + 文档 + 组件 + 资源同一个版本号)。要升级就整包换(见「版本与更新开发包」)。

第 2 步:用 Trae 打开开发包目录

这一步决定了 AI 会不会按云捷规范给你写代码。
  1. Trae 里「文件 → 打开文件夹」,选中你的开发包目录(如 D:\我的插件)。
  2. Trae 会自动识别目录下的 .trae/skills/yunjie-plugin-dev(云捷插件开发技能)。
  3. 然后直接用中文提需求,例如:
    • 用云捷插件开发 skill,做一个批量改标题的插件
    • 「用云捷插件开发 skill,把模板/列表操作插件 改成批量改库存」
    • 「查一下云捷 SDK 里怎么发优惠券」(它会去读 参考/02-SDK-营销.md
想自己查细节时,直接看包里的 参考\ 目录: 00-快速开始01-SDK速查02-营销03-商品04-商机05-售后06-订单评价07-数据存储08-宿主能力09-避坑10-接口清单11-平台能力与组件库

第 3 步:在客户端里关联目录并本地调试

这是「边写边看」的关键,不用上传、不用打包。
  1. 打开云捷电商工具箱客户端 → 登录开发者账号
  2. 进「开发者中心 → 我的应用」,找到(或新建)你的应用,点「版本
  3. 点「选择 / 更换目录」,选中你的开发包目录(选一次就记住了)
  4. 点「本地调试」→ 客户端会开一个应用标签,直接看到你的界面
改完代码 → 回「版本」弹窗再点一次「本地调试」(或关掉应用标签重新打开)就能看到新效果。 本地调试不会上传服务器,随便改。
只有「本地调试」能打开开发者工具:上架后的应用(整包运行)右键里没有「检查元素」, F12 / Ctrl+Shift+I 也都被拦掉(平台防止用户看到插件内部结构)。 所以要调样式、看报错、查网络请求,都在「本地调试」里做
如果界面里的东西「点了没反应 / 按钮不见了」,先按「改了代码怎么看效果」那一节排查(多半是页面缓存了旧文件)。

目录结构与入口

插件就两个文件一眼能认:index.html(入口,界面) + app.js(业务代码)。 推荐用「发布」目录:只有它里面的内容会被打包上传;不用也没关系(老插件照旧整目录打包)。
我的插件\                ← 客户端里选这个当「源码目录」(选**上层这一层**)
├── 发布\                ← 【会上传】要上线运行的文件都放这里
│   ├── 云捷SDK.js       ← 包自带,不要动
│   ├── 资源\            ← 包自带(Vue2 + Element UI 本地文件)
│   ├── index.html       ← 入口(你写)
│   └── app.js           ← 业务代码(你写,ES Module)
├── 笔记.md              ← 【不上传】随便放
└── 设计稿.psd           ← 【不上传】
「本地调试」跑的也是 发布\ 里的代码 → 调试的 = 上传的
没有 发布\ 也不会报错:客户端按老规矩打包整个源码目录 —— 以前开发的插件照旧能打包上传,不受影响。
用了 发布\ 时,「更新开发包」会把 云捷SDK.js资源\ 顺带同步进 发布\

index.html(入口写法)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>我的插件</title>
<!-- UI 资源用本地的,不要改成 CDN -->
<link rel="stylesheet" href="./资源/element-ui/index.css">
</head>
<body>
<div id="app" v-cloak>
  <div class="page-header">
    <span>我的插件</span>
    <el-button size="mini" @click="搜索()">搜索</el-button>
  </div>
</div>

<!-- 依赖:先 Vue,再 ElementUI -->
<script src="./资源/vue.min.js"></script>
<script src="./资源/element-ui/index.js"></script>

<!-- ⚠️ 业务代码必须是 ES Module(这样才 import 得动 云捷SDK.js) -->
<script type="module" src="./app.js"></script>
</body>
</html>

app.js(骨架)

// 只从 SDK 拿能力(不要写 const 云捷 = window.云捷,会白屏)
import 云捷 from './云捷SDK.js'

new Vue({
  el: '#app',
  data() {
    return { 店铺列表: [], 当前标签ID: '', 状态: '' }
  },
  async mounted() {
    this.店铺列表 = await 云捷.店铺列表()   // 只拿到"本应用可用"的店铺
    this.当前标签ID = this.店铺列表[0] ? this.店铺列表[0].标签ID : ''
  },
  methods: {
    /** 搜索商品(每个接口都要 try/catch,失败原因给用户看) */
    async 搜索() {
      try {
        const 结果 = await 云捷.商品.列表(this.当前标签ID, { 标签: 'onSale', 每页: 20 })
        if (结果.code !== 0) return this.$message.error('读取失败:' + (结果.msg || '未知原因'))
        this.状态 = '共 ' + (结果.data?.products?.length || 0) + ' 条'
      } catch (错误) {
        this.$message.error('读取失败:' + (错误 && 错误.message ? 错误.message : 错误))
      }
    }
  }
})
界面用 Vue2 + Element UI(模板就是普通 HTML,不用打包、不用 npm)。文件都用 UTF-8。

业务代码骨架(照着填就行)

90% 的插件都是这个套路:选店铺 → 调接口 → 展示 → 批量操作。
import 云捷 from './云捷SDK.js'

/** 每批最多 20 个(抖店接口限制) */
const 每批上限 = 20

new Vue({
  el: '#app',
  data() {
    return {
      店铺列表: [],       // 有权限的店铺
      当前标签ID: '',     // 当前店铺的标签ID(调接口都用它)
      商品列表: [],       // 表格数据
      页码: 0, 每页: 20, 总数: 0,
      选中商品: [],
      执行中: false,      // 长任务时给按钮加 loading
      结果清单: []        // 成功/失败清单(必须给用户看)
    }
  },
  async mounted() { await this.初始化() },
  methods: {
    /** 初始化:取店铺列表并选中第一家 */
    async 初始化() {
      try {
        this.店铺列表 = await 云捷.店铺列表()
        if (!this.店铺列表.length) return this.$message.warning('这个应用还没有可用店铺,请先在客户端里授权')
        this.当前标签ID = this.店铺列表[0].标签ID
        await this.搜索()
      } catch (错误) {
        this.$message.error('初始化失败:' + (错误 && 错误.message ? 错误.message : 错误))
      }
    },

    /** 搜商品(分页从 0 开始) */
    async 搜索() {
      try {
        const 结果 = await 云捷.商品.列表(this.当前标签ID, { 页码: this.页码, 每页: this.每页, 标签: 'onSale' })
        if (结果.code !== 0) return this.$message.error('搜索失败:' + (结果.msg || '未知原因'))
        this.商品列表 = 结果.data?.products || []
      } catch (错误) {
        this.$message.error('搜索失败:' + (错误 && 错误.message ? 错误.message : 错误))
      }
    },

    /** 批量下架:先确认 → 分批(≤20)→ 汇总成败 */
    async 批量下架() {
      if (!this.选中商品.length) return this.$message.warning('先勾选商品')
      if (!window.confirm('下架 ' + this.选中商品.length + ' 个商品,确定吗?')) return
      this.执行中 = true
      this.结果清单 = []
      for (let i = 0; i < this.选中商品.length; i += 每批上限) {
        const 本批 = this.选中商品.slice(i, i + 每批上限)
        try {
          const 结果 = await 云捷.商品.批量上下架(this.当前标签ID, {
            商品ID列表: 本批.map((项) => 项.product_id), 上架: false
          })
          // 按接口返回的成败逐条记进"结果清单"
          本批.forEach((项) => this.结果清单.push({ 商品ID: 项.product_id, 结果: 结果.code === 0 ? '成功' : '失败', 原因: 结果.msg || '' }))
        } catch (错误) {
          本批.forEach((项) => this.结果清单.push({ 商品ID: 项.product_id, 结果: '失败', 原因: String(错误 && 错误.message ? 错误.message : 错误) }))
        }
      }
      this.执行中 = false
      const 失败数 = this.结果清单.filter((项) => 项.结果 !== '成功').length
      this.$message[失败数 ? 'warning' : 'success']('完成:成功 ' + (this.结果清单.length - 失败数) + ',失败 ' + 失败数)
    }
  }
})
金额单位一律是1300 = 13 元);写接口要带店铺令牌 { 令牌: await 云捷.取店铺令牌(店铺ID) }。 具体接口签名见包内 参考/01-SDK速查.md

常用能力速查

只列最常用的;完整签名看包内 参考\ 对应文件。
要做什么怎么调(都在 云捷 上)看哪个文档
拿店铺列表 / 令牌云捷.店铺列表()云捷.取店铺令牌(店铺ID)01-SDK速查
通用请求云捷.请求(标签ID, 路径, { 方法, 查询, 体, 内容类型, 不补来源参数 })01-SDK速查
营销(直降/满减/优惠券/新人券)云捷.营销.* / 云捷.优惠券.*02-SDK-营销
商品(列表/详情/SKU/主图/上下架/运费模板)云捷.商品.*03-SDK-商品
商机(搜索 → 可报商品 → 报名)云捷.商机中心.*04-SDK-商机
售后(导出/详情/物流/退货策略)云捷.售后.*05-SDK-售后
订单 / 评价云捷.订单.* / 云捷.评价.*06-SDK-订单评价
临时数据 / 正式数据云捷.缓存(会被清)、云捷.数据库(一个应用一个独立库)07-数据存储
文件读写 / 下载图片 / 导出云捷.文件.*云捷.应用文件.*08-宿主能力
定时任务(无人值守)云捷.定时.注册(...)08-宿主能力
往应用页面右键菜单里加自己的项云捷.菜单.设置([{ 名称, 点击 }]) / 清除()08-宿主能力 9
把一个页面做成常驻整页(与「云捷科技」并列,侧边栏「功能」点开;登记即常驻,跟随客户端启动)云捷.首页.注册面板({ 名称, 入口, 说明, 权限 }) / 状态() / 设置角标(n) / 取消()08-宿主能力 10
应用内收费:知道"现在是谁在用"(判断这个账号买过没有)云捷.身份.票据() → 你的服务端调 POST /api/app/identity/verify 验签换出 归属账号ID / 店铺ID08-宿主能力 11
浏览器自动化(抓页面接口 / 自动操作)云捷.浏览器.*08-宿主能力
调站外接口 / 算抖音签名云捷.网络.请求(...)云捷.签名.aBogus(...)08-宿主能力
AI(对话 / 出图)云捷.AI.*08-宿主能力
可复用组件(唯一组件:SKU 编码搜索 <sku-search>包内 组件\ 目录,复制进你的插件用;商品ID 必须用它或商品列表勾选拿到11-平台能力与组件库 4
window.云捷 只是底层桥,没有上面的业务封装。写插件一律 import 云捷 from './云捷SDK.js'

铁律与交付前自查

这几条踩一次就够记一辈子,交付前逐条打勾。

铁律(违反必定跑不通)

  1. 模板里调用中文方法必须带括号@click="搜索()"@change="换店铺()"; 写成 @click="搜索" 会「只读函数引用不调用」→ 点了毫无反应、Console 还不报错。
  2. 自定义组件标签不要自闭合:页内模板里 <el-input ... /> 会把**后面的兄弟节点整片吞掉** (表现:该有的按钮凭空消失)→ 必须写 <el-input ...></el-input>。 只有 <img /><br /> 这类 HTML 空元素可以自闭合。
  3. 模板里用到的字段,data/computed/methods 里必须真存在:改字段名要同步「data 定义 + 模板引用 + 方法里读写」三处, 否则整页 ReferenceError,点哪都没反应。
  4. 不要用 localStorage 存业务数据:用 云捷.缓存 / 云捷.数据库
  5. 【强制】需要用户给"商品ID"时,不要让用户手输商品ID:只允许两种方式 —— ① 页面里嵌 <sku-search>(包内 组件\SKU搜索.js,组件库唯一的组件, 用户贴 SKU编码 → 自动搜出商品ID);② 用 云捷.商品.列表() 拉列表让用户勾选。 拿到的是商品ID数组,直接传给批量接口 / 创建活动。详见 11-平台能力与组件库 4.1。
  6. 每个接口都要 try/catch 并把失败原因展示给用户(不要只说"失败了")。

交付前自查

  • 所有事件绑定都带括号(搜「纯中文方法名、无括号」的绑定)
  • 没有自闭合的自定义组件标签(搜 <el-[a-z0-9-]+[^<>]*/>
  • 用了「发布」目录的话:要上线的文件都放进了 发布\(源码 / 笔记 / 文档放外面不会被上传)
  • 入口是 type="module" + import 云捷 from './云捷SDK.js'(没有 const 云捷 = window.云捷
  • 有全局错误条(window.onerror + unhandledrejection),报错看得见
  • 金额按「分」处理;列表分页;批量每批 ≤ 20
  • 多店铺循环一家失败不影响其他家,最后汇总成功/失败清单
  • 危险操作(删除/作废/批量)有二次确认
  • 没有引用 CDN(UI 资源用包里的本地文件)

改了代码怎么看效果

本地调试是「读你的磁盘目录」,所以改完必须重新加载页面。
  1. 改完 app.js / index.html,保存(Ctrl+S)
  2. 客户端「开发者中心 → 我的应用 → 版本」再点一次「本地调试」, 或者关掉那个应用标签重新打开
  3. 看界面右上角的「构建标记」之类的版本号,确认跑的是新代码(建议你在自己的插件里也放一个)
插件页会被客户端禁缓存(脚本带时间戳、响应头 no-store)。如果你还看到旧界面, 先把应用标签关掉重开;仍不行就重启客户端。

常见报错与坑

症状 → 原因 → 怎么改。
症状原因与改法
点按钮没有任何反应,也不报错 模板里中文方法名没带括号:@click="搜索" → 改成 @click="搜索()"
该有的按钮整片不见了(弹窗里没有"确定") 上面某个自定义标签写成自闭合 <el-input ... /> 把后面的兄弟节点吞了 → 补结束标签。
整页白屏 / 点哪都没反应 模板里引用了不存在的字段(ReferenceError)。检查 data/computed/methods 里有没有这个字段; 先看页面顶部的红色错误条、再看 Console。
接口返回空 body / 被风控 写接口(如商机提交)要加 不补来源参数: true;请求头 / 签名参数必须与真实浏览器一致。 偶发空 body 建议重试 2~3 次(每次间隔 1 秒)。
弹窗能出来,但里面没有"确定/取消" 同上(自闭合吞节点)。另外:需要输入的弹窗建议用页面内 el-dialog + el-input, 别用 $prompt / $confirm(本环境可能不弹)。
图片能下载但画布处理报安全错误 外链图片跨域会污染画布 → 必须先用 云捷.文件.下载 落到本地,再 云捷.文件.读取(路径, 'base64') 读回来处理。
接口返回的字段看不懂 表格里用抖店返回的英文原名;界面文案写中文。失败原因在 msg(或 errno、内层 data.msg)。
更多坑(含实测证据)看包内 参考\09-避坑.md。遇到新坑建议补进那份文档,下次 AI 不会再犯。

打包提交审核

不用命令行,客户端里点按钮就行。
  1. 客户端「开发者中心 → 我的应用 → 版本」→ 点「打包提交审核」 (把打包来源压成 zip 上传:有「发布」目录就只打它,没有就打整个源码目录; 上传时会显示进度 / 已传大小 / 预估剩余时间
  2. 版本号用平台建议值(YYYYMMDD-序号),填一句更新说明
  3. 等平台审核;审核通过后上架应用市场
  4. 用户在客户端应用市场里安装 / 订阅后即可使用(插件是整包下发到客户端内存里运行,不是从服务器拉页面; 用户那边下载时同样有进度条
用了「发布」目录时:源码、笔记、设计稿、文档放在 发布\ 外面,一律不会上传到服务器; 「源码目录」要选包含 发布\ 的那一层,不要选 发布\ 本身。
没建 发布\ 的老插件不受影响 —— 仍是整目录打包,行为跟以前一样。
提交前把「交付前自查」过一遍;界面里别留调试用的日志面板、测试按钮、写死的店铺名。

版本与更新开发包

两个「版本」别搞混:插件的版本 vs 开发包的版本。
版本是什么在哪看 / 怎么升
插件版本 你这一版插件(提交审核用的) 「我的应用 → 版本」里提交时递增;用户看到的是这个
开发包版本 SDK + 文档/技能 + 组件 + 资源这一整套的版本(写在 云捷SDK.js 开头的 开发包版本 「版本 → 开发包版本」看最新版本与更新说明;点「更新开发包(整包)」整包覆盖进你的目录
「更新开发包(整包)」会把 云捷SDK.js、SDK 更新日志、全部参考文档、模板 / 组件 / 资源一起换成同一版, 不会动你自己写的 index.html / app.js / 图片。 所以平台一更新开发包(新能力、新避坑),你点一下就同步了。

完整流程清单(照着做一遍就能上架)

第一次做建议按顺序走;熟练后 6~11 一步做完。
  1. 装 Trae:官网 trae.com.cn → 下载 IDE(Windows x64)→ 安装(非系统盘、英文路径)→ 手机号登录
  2. 拿开发包:本页右上「下载开发包」→ 解压到 D:\我的插件
  3. 用 Trae 打开这个目录(skill 自动生效)
  4. 照抄骨架:把 模板\最小插件\index.html + app.js 复制到包根
  5. 关联目录:客户端「开发者中心 → 我的应用 → 版本 → 选择/更换目录」
  6. 本地调试:点「本地调试」,先确认骨架能跑起来
  7. 提需求给 AI:「用云捷插件开发 skill,做一个 XXX 的插件」,然后自己按需改
  8. 边改边看:保存 → 关掉应用标签重开(或再点本地调试)
  9. 跑接口:先取 云捷.店铺列表(),用 标签ID 调业务接口;失败原因要显示给用户
  10. 自查:「铁律与交付前自查」逐条过一遍(括号、自闭合、字段、错误条、分页 ≤20、二次确认)
  11. 打包提交审核 → 填版本号与更新说明 → 等审核
  12. 上架后:用户在应用市场安装;后续要改就重复 7~11; 平台更新了开发包,就点「更新开发包(整包)」同步
最小可用版本:第 1~6 步 + 第 11 步就能上架一个「能用的插件」,先跑通闭环再慢慢加功能。

常见问题(FAQ)

一定要用 Trae 吗?

不一定。VS Code 也能写(插件就是 HTML + JS,不需要打包工具)。用 Trae 的好处是开发包自带的 .trae/skills 会让 AI 按云捷规范写代码、自动查接口文档、避开已知坑。

插件要 npm install / 打包构建吗?

不需要。Vue2 和 Element UI 都是开发包里的本地文件,浏览器直接跑;提交流程也是客户端点按钮自动压缩上传。

插件能直连数据库吗?能自己发 HTTP 吗?

不能直连数据库(平台不给)。发请求走 云捷.请求(抖店接口,自带店铺登录态与签名)或 云捷.网络.请求(站外接口,主进程发,绕开跨域)。

为什么我改了代码,界面没变?

本地调试是读磁盘的,但页面会被缓存 → 关掉应用标签重新打开(或再点一次「本地调试」)。仍不行就重启客户端。

为什么点了按钮一点反应都没有,也不报错?

九成是模板里中文方法名没带括号(见「铁律」第 1 条);其次是整页渲染崩了(字段不存在,先看页面顶部错误条)。

多开 / 多店铺怎么处理?

客户端支持同时开多个应用标签;插件自己按 云捷.店铺列表() 逐个处理即可。 多店铺循环要「一家失败不影响其他家」,最后给出成功/失败清单。

开发包更新了,我要重写吗?

不用。点「更新开发包(整包)」覆盖 SDK 与文档即可(不动你的代码);如果新版本的接口签名变了, 看 SDK 更新日志里对应版本的说明改一下调用点。

想加新能力 / 发现 SDK 不够用怎么办?

把需求提给平台(说明你想调什么接口、要什么参数),平台会把能力封装进 SDK 再随开发包下发 —— 插件永远只调 SDK,不自己造轮子。

云捷电商工具箱 · 开发者文档 —— 插件开发只调 SDK;有问题先看包内 参考\09-避坑.md