# 云捷电商工具箱 · 开发者文档

> 本文档由服务端**实时生成**：接口清单直接读数据库，所以永远是最新版本。
>
> **建议先读**：「七、插件开发避坑清单」（实战踩坑经验）+「八、可复用组件」（可直接下载，如 SKU 编码搜索）。

## 一、整体结构

```
┌───────────────┐   IPC    ┌──────────────────────────────┐
│ 插件（JS/TS）  │ ───────► │ 云捷客户端（Electron）         │
└───────────────┘          │  ├─ 本地签名服务（浏览器协同）  │
                           │  └─ 店铺标签页（已登录抖店）    │
                           └──────────────────────────────┘
```

**核心结论：你不需要实现抖店的签名算法（a_bogus）。**

所有抖店接口调用都由「店铺页面自身」发出，页面内置的 bdms 会自动加签名并带上该店铺 Cookie。
你只需要：**选定店铺 + 给出接口地址**。

## 二、SDK 用法

### 2.1 第一步：把「插件开发包」解压出来，并搭好「发布」目录（一次搞定，之后**不用再下载**）

开发前先下载**一次**开发包：客户端「开发者 → 开发文档 → 下载开发包」
（接口 `GET /api/docs/kit.zip`，一个包全带）。

**推荐**用「发布目录」结构：只有 `发布/` 里的内容会被打包上传，其他一律不上传 —— 所以插件目录建议长这样：

```
我的插件/                  ← 客户端里选这个当「源码目录」（选**上层这一层**，不是 发布/ 本身）
├── 发布/                  ← 【会上传】要上线运行的文件都放这里
│   ├── index.html             入口（也可 main.html / index.js / main.js，客户端自动找）
│   ├── app.js                 你的逻辑（可拆多个文件）
│   ├── 云捷SDK.js              ← 从开发包复制（⚠️ 不要自己手写 SDK，手写的一定不对）
│   ├── 资源/vue.min.js         ← 从开发包复制（Vue，本地文件）
│   ├── 资源/element-ui/…       ← 从开发包复制（index.js / index.css / fonts）
│   └── 组件/…                  ← 组件库组件（如 组件/SKU搜索.js，需要就用，见「八、可复用组件」）
├── 笔记.md                 ← 【不上传】随便放
└── 设计稿.psd              ← 【不上传】
```

- **源码、笔记、设计稿、文档放在 `发布/` 外面，一律不会上传到服务器**
- **没有「发布」目录也不会报错**：客户端会按**老规矩打包整个源码目录** ——
  以前开发的插件（根目录直接就是 index.html + app.js）照旧能打包上传，**不受这个约定影响**；要不要用由你定
- 「本地调试」跑的也是 `发布/` 里的代码 → **调试的 = 上传的**
- 也可以让开发包的 `.trae/skills/`、`模板/`、`组件/` 留在上层目录，你的代码只写在 `发布/` 里

> **SDK 目录 + 组件库 + 开发包**三份东西都在**同一个 zip** 里，下这一次就够，之后不用再下载任何东西。

入口 HTML 按下面顺序用**相对路径**静态引入（不要走 CDN）：

```html
<link rel="stylesheet" href="./资源/element-ui/index.css" />
<script src="./资源/vue.min.js"></script>
<script src="./资源/element-ui/index.js"></script>
```

SDK、组件库、UI 资源、六个可跑模板，以及**全部分模块开发文档**都在这个包里，拿这一份就够了。

**开发包版本（要不要升级，你自己决定）**

「开发包」= SDK + 开发文档 + 技能参考 + 组件 + 资源，**整套只有一个版本号**，
就写在 SDK 文件开头的 `const 开发包版本 = 'x.y.z'` 里，插件里可以读 `云捷.开发包版本`。
更新**不需要改业务代码**，用客户端「更新开发包」把整个包覆盖进插件目录即可（文档与 SDK 同一版）。

| 想干什么 | 怎么做 |
|---|---|
| 看当前开发包版本 + 每个版本改了什么 | `GET /api/docs/sdk/info`（当前版本 / 更新日志） |
| 拿最新开发包（SDK + 文档 + 组件 + 资源） | `GET /api/docs/kit.zip` |
| 看我的插件用的是哪个开发包版本、一键更新 | 客户端「开发者中心 → 我的应用 → 版本 → 开发包版本」 |

**开发包（推荐用法：用 Trae 打开开发包目录）**

开发包解压后，里面已经带好：

| 看到什么 | 干什么用 |
|---|---|
| `.trae/skills/yunjie-plugin-dev/` | **Trae 开发 skill**（打开该目录即自动生效）：入口 `SKILL.md` + 参考 `00 快速开始` / `01 SDK速查` / … / `11 平台能力与组件库` |
| `云捷SDK.js` / `资源/` / `组件/` | SDK 与 UI 资源、可复用组件（本地文件，**不要走 CDN**） |
| `模板/` | 六个能直接跑的模板（最小插件 / 列表操作插件 / 批量任务插件 / 定时器示例 / 首页面板示例 / 搜索商品示例） |
| `使用说明.txt` | 一屏导航（包里有什么、怎么开始） |

> 开发文档**全部收在 skill 的参考里**（本文档就是这些参考的汇总版，供线上查阅）；
> AI 会先读 `SKILL.md`，再按需只读 1~2 份参考，所以不会出现"文档太大、塞不进 AI 工具"的问题。

**升级 SDK 时把文档一起换新**：客户端「我的应用 → 版本 → **更新开发包（SDK + 文档）**」——
一次把 `云捷SDK.js`、SDK更新日志、skill 全部分模块参考**一起**换成最新
（新 SDK 常带新开发方案，只换 SDK 会变成"新 SDK + 旧文档"）。

- 它**不会动**你自己的 `index.html` / `app.js`，也不动 `模板/`、`组件/`、`资源/`
- 用了 `发布/` 目录时，「更新开发包」会**顺带把 `云捷SDK.js` 与 `资源/` 同步进 `发布/`**，
  保证真正跑起来、被打包上传的那份也是新版；`模板/`、文档这类**不会**进 `发布/`（它们不该上传）
- 打包提交审核**只打包 `发布/` 目录**（源码、笔记、文档放在外面一律不上传）

### 2.2 调用 SDK

```js
import 云捷 from './云捷SDK.js'

// 1) 取店铺列表
const 店铺 = await 云捷.店铺列表()

// 2) 通用请求（自动处理签名、Cookie、标签打开）
const 数据 = await 云捷.请求(店铺[0].店铺ID, '/marketing/promotion/v1/listFlashWithTimeLimit', {
  查询: { page: 1, size: 20 }
})

// 3) 取店铺令牌（写接口需要，如创建活动 __token）
const 令牌 = await 云捷.取店铺令牌(店铺[0].店铺ID)
```

**注意**：调用时**不需要关心店铺标签是否打开**，SDK 会自动打开并等页面就绪。

### SDK 业务接口速查

除下列封装外，任何抖店接口都可用 `云捷.请求(标签ID, 接口地址, { 方法, 查询, 体, 内容类型 })` 直接调用。
金额单位一律是**分**；时间参数可传 `Date` / 时间戳 / `'YYYY-MM-DD HH:MM:SS'`，SDK 会自动转换。

| 模块 | 常用方法 |
|---|---|
| `云捷.营销.单品直降` | 活动列表 / 活动详情 / 活动商品明细 / 商品列表 / 参与商品 / 创建活动 / 编辑活动 / 作废活动 / 按商品查SKU / 检测可报名 / 校验活动 |
| `云捷.营销.多件满减` | 列表 / 详情 / 参与商品 / 创建 / 作废 / 可用商品 |
| `云捷.营销.优惠券` | 列表 / 详情 / 创建 / 作废 / 增发 / 检测可用 |
| `云捷.营销.新人券` | 列表 / 详情 / 创建 / 作废 / 可用商品 |
| `云捷.营销.惊喜券` | 列表 / 详情 / 模板 / 创建 / 停用 / 可用商品（精准营销 · 人群券；列表不传状态 = 3 生效中，传空串 = 全部） |
| `云捷.营销.活动` | 即将到期 / 商品参与活动 / SKU促销价 / SKU促销列表 |
| `云捷.商品` | 列表 / 无销量列表 / 详情 / SKU列表 / 主图 / 批量上架 / 批量下架 / 批量删除 / 批量改运费模板 / 设置定时开售 / 取消定时开售 |
| `云捷.商机中心` | **关键词搜索（商机列表：关键词/页码/每页条数/分类）** / 列表 / 商品列表（线索ID/一级分类ID） / 线索详情（线索ID） / 批量提交（线索ID + 商品列表，**不补来源参数**） |
| `云捷.评价` | 列表 / 批量回复 / 评价分析 / 品质退款分析 |
| `云捷.售后` | 导出任务 / 导出进度 / 售后单详情 / 售后物流 / 退货包裹轨迹 / 策略列表·详情·创建·更新·**删除** / 退货地址列表·**删除退货地址** / 识别地址 / 发送地址验证码 / 创建退货地址 / 运费模板列表·详情·创建·更新·**删除** |
| `云捷.订单` | 到手价 / 详情 / 物流 / 发票列表 |
| `云捷.店铺` | 违规列表 / 违规详情 / 赔付单 / 举报列表 / 提交举报 / 举报预检 |
| `云捷.店铺经营` | 首页经营数据 / 检测登录状态 / 结算账户 / 店铺主体 / 账单查询 |
| `云捷.素材` | 推荐标题 / 预测类目 / 推荐素材图 / 好图复刻提交·查询 |
| `云捷.定时` | 注册 / 当前任务 / 列表 / 删除 |
| `云捷.浏览器` | 打开工作页 / 关闭 / 页面信息 / 执行JS / 等待元素 / 点击 / 输入 / 截图 / 拦截返回 / 拦截改写 / 取消拦截 / 监听响应 |
| `云捷.缓存` | 读 / 写 / 读多个 / 写多个 / 删 / 有 / 键列表 / 全部 / 条数 / 清空（可设存活时间） |
| `云捷.数据库` | 插入 / 插入多条 / 查询 / 查询一条 / 计数 / 更新 / 删除 / 清空 / 集合列表 / 删除集合 |

> 图片上传、视频上传、白底图涉及 multipart 上传与字节 VOD 直传（需要本地文件与 AWS 签名），
> 不在 SDK 范围内，请用 `云捷.浏览器.*` 在工作页里完成。
> 飞鸽客服 `pcbackstage/*`（飞鸽工作台，非店铺页面）**不可**通过 SDK 调用（已在「接口管理」登记，仅作说明）。
> 详细参数说明见配套的《应用开发文档》（客户端「开发者 → 开发文档」页）。

### 2.3 数据存储：`云捷.缓存` / `云捷.数据库` / `云捷.文件`

两套能力都由**客户端主进程**实现（插件只是调用），**一个应用一个独立库** —— 应用之间互不可见。

| 存什么 | 用哪个 | 存放位置 | 清缓存时 |
|---|---|---|---|
| 临时 / 可随时重建的数据（接口结果、上次同步时间、临时状态…） | `云捷.缓存` | 应用目录 `缓存/` | **会被清掉** |
| 要长期保存的业务数据 | `云捷.数据库` | 应用目录 `数据/数据库/` | 保留 |
| 要长期保存的**单个文件**（配置 JSON、导出的报表…） | `云捷.文件`（别名 `云捷.应用文件`） | 应用目录内**相对路径** | 保留 |

**文件**（按相对路径读写，只能碰自己的应用目录；想"记住上次填的表单"就用它）：

```js
await 云捷.文件.写入('配置/创建配置.json', JSON.stringify(配置))
const { 内容 } = await 云捷.文件.读取('配置/创建配置.json')   // 不存在 → { 成功:false, 消息 }（**不抛错**）
await 云捷.文件.删除('配置/创建配置.json')
```

**缓存**（键值，内存读写 + 合并落盘，读写很快；支持"存活时间"自动过期）：

```js
await 云捷.缓存.写('商品列表', 列表, 5 * 60 * 1000)   // 5 分钟后自动失效（不传 = 永不过期）
const 列表 = await 云捷.缓存.读('商品列表', null)      // 拿不到 → 默认值 null
await 云捷.缓存.删('商品列表')
```

**数据库**（集合 ≈ 表，行 ≈ 记录，每条自动带 `_id`）：

```js
// 插入 → 返回带 _id 的那一行
const 行 = await 云捷.数据库.插入('任务', { 标题: '批量改价', 状态: '待执行' })

// 查询（条件 + 排序分页）
const 列表 = await 云捷.数据库.查询('任务', { 状态: '待执行' }, { 排序: { _id: -1 }, 条数: 20 })
const 一条 = await 云捷.数据库.查询一条('任务', { _id: 行._id })
const 数量 = await 云捷.数据库.计数('任务', { 状态: '待执行' })

// 更新：直接给字段 = 合并；也支持 $set / $inc / $unset / $push
await 云捷.数据库.更新('任务', { _id: 行._id }, { 状态: '已完成' })
await 云捷.数据库.更新('任务', { _id: 行._id }, { $inc: { 执行次数: 1 } })

// 删除
await 云捷.数据库.删除('任务', { _id: 行._id })
```

查询条件（多个字段是"与"关系）：等值 `{ 状态: 'on' }`、
比较 `{ 价格: { $gte: 100 } }`（`$gt/$gte/$lt/$lte/$ne/$in/$nin/$like`）；
字段名支持点路径：`{ '商品.id': 123 }`。

> 建议：**别再用 `localStorage` 存业务数据**（容量小、清一次缓存就没了、还可能跨插件串数据）。
> 临时的用 `云捷.缓存`，正式数据用 `云捷.数据库`，单个配置文件/报表用 `云捷.文件`。

## 三、接口清单

## 平台一览（先看这里：六个平台别调混）

| 平台 | 怎么调 | 接口清单在哪 |
|---|---|---|
| **抖店**（fxg.jinritemai.com） | `云捷.请求(标签ID, 路径, 选项)`，或 `云捷.商品/营销/评价/售后/订单/发货/申诉/店铺/店铺经营/商机中心/素材/拦截` | **本文件下面按分组列出**（后台「接口管理」实时维护） |
| **精选联盟**（巨量百应） | `云捷.平台.请求(标签ID, '精选联盟', 路径)` / `云捷.精选联盟` | 本文件下面按平台列出；怎么调、有哪些坑见 `参考/17-多平台接口清单.md` 第 2 节 |
| **电商罗盘** | `云捷.平台.请求(标签ID, '电商罗盘', 路径)` / `云捷.电商罗盘` | 同上（本文件 + `参考/17-多平台接口清单.md` 第 3 节） |
| **巨量千川** | `云捷.平台.请求(标签ID, '巨量千川', 路径)` / `云捷.千川` | 同上（本文件 + `参考/17-多平台接口清单.md` 第 4 节） |
| **飞鸽**（工作台 / 客服数据） | `云捷.飞鸽数据.*`（催评是 WS 长连接，走 `云捷.飞鸽`） | 本文件下面按平台列出；字段口径见 `参考/18-飞鸽数据接口清单.md` |
| **店管家**（fx*.dgjapp.com） | `云捷.店管家.*`（**独立账号**：登录 / 店铺列表 / 订单 / 售后 / 厂家 / 出单量） | 本文件 + `参考/17-多平台接口清单.md` 第 5 节 |

> 一句话分家：**抖店**=店铺后台；**精选联盟 / 电商罗盘 / 巨量千川**=抖店生态的另外三套后台（登录态由客户端
> 从抖店登录态换出来，走 `云捷.平台`）；**飞鸽**=抖店客服工作台与客服数据；**店管家**=独立的代发/分销 ERP
> （自己一套账号密码，走 `云捷.店管家`）。
> 各平台**成功码不同**：抖店 `code===0`、千川财务 `code===1`、千川广告 `status_code===0`。

## 一、抖店接口（按分组）

## 一、抖店接口（按分组）

### 单品直降

#### 单品直降活动列表(限时)

- **请求**：`GET /marketing/promotion/v1/listFlashWithTimeLimit`
- **说明**：查询店铺的单品直降（限时限量购）活动列表。来源：抖店页面接口
- **参数说明**：

```
campaign_status：活动状态（1未开始 2进行中 3已失效 4已结束 6处理中；不传=全部）
shop_stype：店铺类型，一般固定 1
business_code：活动类型，单品直降固定 LimitTime（限时抢购 LimitTime / 限量抢购 LimitQuantity / 普通降价促销 OrdinaryTimeBuy）
page / size：分页（⚠️ 参数名是 size，不是 pageSize）
product_id：按商品筛选（可空）
title：按活动名称筛选（可空）
_bid：固定 ffa_flash
_lid：固定 391768877673
__token：仅写接口需要（用 云捷.取店铺令牌(店铺ID) 取），查列表不用传
```
- **返回说明**：

```
data.flash_list：活动数组，元素含 campaign_id / title / status 等
```
- **示例请求体**：

```json
campaign_status=1&shop_stype=1&business_code=LimitTime&page=1&size=20&_bid=ffa_flash&_lid=391768877673&appid=1
```
- **示例返回**：

```json
{"code":0,"data":{"flash_list":[{"campaign_id":"123","title":"夏季特惠"}]}}
```

### 多件满减

#### 满减活动详情

- **请求**：`GET /marketing/activity/v1/get_full_discount_activity`
- **说明**：查询满减/满件活动的详情。来源：抖店页面接口
- **参数说明**：

```
activity_id：活动ID（必填）
```
- **返回说明**：

```
data：活动详情，含时间、折扣、状态等
```
- **示例返回**：

```json
{"code":0,"data":{"activity_id":"123","title":"夏季特惠"}}
```

#### 满减活动商品信息

- **请求**：`GET /marketing/activity/v1/get_full_discount_product`
- **说明**：查询满减活动参与的商品（支持逗号分隔多个商品ID）。来源：抖店页面接口
- **参数说明**：

```
activity_id：活动ID（必填）
page / pageSize：分页
```
- **返回说明**：

```
data：商品数组
```
- **示例返回**：

```json
{"code":0,"data":{"products":[]}}
```

#### 创建多件满减活动

- **请求**：`POST /marketing/activity/v1/create_full_discount_activity`
- **说明**：创建多件满减（跨品满N件优惠）活动。体：{ full_discount_activity: { activity_name, activity_products[{product_id,img,max_price,min_price,name,stock_num}], activity_type:2, discount_type（1打折/3立减）, discounts[{condition_value（满N件）, discount（打折=折÷10、立减=元×100）}], enable_use_coupon:true, start_time, end_time }, async:true }；返回 **activity_id 在顶层**。用 云捷.营销.多件满减.创建()。来源：抖店页面接口
- **参数说明**：

```
标题、开始/结束时间、折扣、参与商品与 SKU 列表；__token 用 SDK 的 取店铺令牌 获取
```
- **返回说明**：

```
code=0 表示创建成功，data 内含活动ID
```
- **示例请求体**：

```json
{
  "title": "夏季特惠",
  "start_time": "2026-09-11 00:00:00",
  "end_time": "2026-09-20 23:59:59",
  "promotion_goods": [],
  "__token": "从 云捷.取店铺令牌(店铺ID) 获取"
}
```
- **示例返回**：

```json
{"code":0,"data":{"activity_id":"123"}}
```

### 店铺经营

#### 检测登录状态

- **请求**：`GET /common/index/index?appid=1`
- **说明**：店首页信息接口，用于检测店铺登录状态并取店铺ID/名称/令牌。来源：抖店页面接口
- **参数说明**：

```
appid：固定 1
```
- **返回说明**：

```
data.id：店铺ID
data.shop_name：店铺名称
data.shop_logo：店铺Logo
data.token：店铺令牌
```
- **示例返回**：

```json
{"code":0,"data":{"id":"287560243","shop_name":"云策优选","token":"834de40c..."}}
```

### 单品直降

#### 单品直降活动详情(按活动ID)

- **请求**：`GET /marketing/promotion/v1/get_time_buy_detail`
- **说明**：按活动ID查询单品直降活动详情（含参与商品与SKU直降价）。来源：抖店页面接口

#### 单品直降商品列表

- **请求**：`GET /marketing/promotion/v1/getFlashAndGoods`
- **说明**：查询单品直降活动下的商品列表。来源：抖店页面接口

#### 创建单品直降活动

- **请求**：`POST /marketing/promotion/v1/createFlashAndGoods`
- **说明**：创建单品直降（限时抢购）活动。来源：抖店页面接口

#### 编辑单品直降

- **请求**：`POST /marketing/promotion/v1/editFlashAndGoods`
- **说明**：编辑已有单品直降活动。来源：抖店页面接口

#### 删除/作废单品直降

- **请求**：`POST /marketing/promotion/v1/setFlashStatus`
- **说明**：作废或删除单品直降活动（status=2作废 3删除）。来源：抖店页面接口

#### 按商品查询活动(SKU)

- **请求**：`POST /marketing/promotion/v1/batch_query_sku_list_v2`
- **说明**：按商品ID批量查询可用于活动的SKU列表（**组件库「SKU搜索」的「导入商品ID」也用它补商品详情**：名称 / 主图 / 价格区间 / 库存合计）。体：{ channel_products: [{ product_id }]（**一次 ≤ 100 个**）, limit_stock_type（默认 1）, activity_tool_type（26 单品直降 / 43 评价有礼…）, business_code, start_time, end_time（活动起止·秒级字符串） }；返回 data.channel_products[]（每项含 product_id / title / img / sku_list[{origin_price, origin_stock}]）；原版节奏：每 100 个一批、批间 600 毫秒。用 云捷.单品直降.按商品查SKU()。来源：抖店页面接口

### 多件满减

#### 多件优惠活动列表

- **请求**：`GET /marketing/activity/v1/query_full_discount_activity`
- **说明**：查询多件满减（满N件优惠）活动列表（查询 page/pageSize/activity_name/activity_status；activity_status：0全部 1未开始 2进行中 3已结束 4已失效）。用 云捷.营销.多件满减.列表()。来源：抖店页面接口

### 单品直降

#### 校验活动(创建/编辑前)

- **请求**：`POST /marketing/promotion/v1/check_promotion_validation`
- **说明**：创建/编辑单品直降前先校验（活动时间、商品是否与其它活动冲突）。体：{scount_type:2, start_time, end_time, product_infos:[{product_id, channel_type:0, channel_id:'0'}]}。来源：抖店页面接口

#### 创建活动前校验(哪些商品不能创建)

- **请求**：`POST /marketing/promotion/v1/checkFlashAndGoods`
- **说明**：按与「创建活动」同一份请求体做创建前校验。返回 data.campaign_check_res{商品ID: {msg}}（有 msg = 该商品不能创建，避免建了一半失败）。⚠️ 与「校验活动(创建/编辑前)」不是同一条（那条查的是活动冲突）。用 云捷.营销.单品直降.创建前校验()。来源：抖店页面接口

#### 局部修改活动计划

- **请求**：`POST /marketing/promotion/v1/part_update_time_buy`
- **说明**：局部改活动计划：改时间 / 库存 / 参与商品等，传什么字段就改什么（体如 {activity_id, begin_time, end_time, promotion_goods}）。用 云捷.营销.单品直降.局部修改() / 云捷.营销.限时抢购.局部修改()。来源：抖店页面接口

#### 失败商品记录(按活动ID拿操作批次)

- **请求**：`POST /marketing/promotion/v1/getFailedFlashAndGoodsRecord`
- **说明**：按活动ID查一次操作批次，拿 operate_id。体 {activity_id}；返回数组，元素含 operate_id。⚠️ 同路径还有 GET 口径（云捷.营销.限时抢购.失败记录()）。来源：抖店页面接口

### 多件满减

#### 停用多件优惠活动

- **请求**：`POST /marketing/activity/v2/disable_product_activity`
- **说明**：停用（作废）多件优惠 / 满减 / 多件立减活动。体只传 `{ activity_id }` —— **平台/原版不带 `status`**（照原版页面代码核过；只有状态 1 未开始 / 2 进行中 能停）。用 云捷.营销.满减.停用活动() / 云捷.营销.多件满减.作废()。来源：抖店页面接口

### 单品直降

#### 失败商品明细(按操作批次)

- **请求**：`POST /marketing/promotion/v1/getFailedFlashAndGoods`
- **说明**：按操作批次ID（operate_id）查具体哪些商品没建成功、原因是什么。用 云捷.营销.单品直降.失败商品列表()。来源：抖店页面接口

### 优惠券

#### 优惠券列表

- **请求**：`GET /marketing/coupons/v1/list`
- **说明**：查询店铺优惠券列表。来源：抖店页面接口

### 单品直降

#### 风控剔除商品

- **请求**：`GET /marketing/promotion/v1/getGovernanceRiskProducts`
- **说明**：查被平台风控剔除的商品（活动里没生效的）；创建前也能用它提示哪些商品不可投。查询 operate_id。用 云捷.营销.单品直降.风控商品() / 云捷.营销.限时抢购.风控商品()。来源：抖店页面接口

### 优惠券

#### 创建/停用/加库存/详情优惠券

- **请求**：`POST /marketing/coupons/v1/shopcoupons`
- **说明**：**创建券** = POST 本路径；**券详情** = GET `/marketing/coupons/v1/shopcoupons/{coupon_meta_id}`、**作废 / 增发** = POST 同一条带 id 的路径（SDK 已按 id 拼好：云捷.营销.优惠券.详情() / 作废() / 增发()）。来源：抖店页面接口

### 新人优惠券

#### 新人优惠券列表

- **请求**：`GET /marketing/union_allowance/v1/list_record`
- **说明**：查询新人专享优惠券活动列表。⚠️ 新人礼金（云捷.营销.新人礼金.列表）走**同一条路径的 POST 口径**（查询与体带 _bid=ecom_market_shop/appid=1）。来源：抖店页面接口

#### 新人优惠券详情

- **请求**：`GET /marketing/union_allowance/v1/get_record_detail`
- **说明**：查询新人券活动详情（apply_id）。⚠️ 新人礼金（云捷.营销.新人礼金.详情）同路径走 POST。来源：抖店页面接口

#### 创建新人优惠券

- **请求**：`POST /marketing/union_allowance/v1/create_apply`
- **说明**：创建新人专享优惠券活动（新人礼金同路径，体不同）。来源：抖店页面接口

#### 停用新人优惠券

- **请求**：`POST /marketing/union_allowance/v1/disable_apply`
- **说明**：停用（失效）新人优惠券活动。来源：抖店页面接口

### 活动查询

#### 即将过期活动列表

- **请求**：`POST /marketing/smart_activity/v1/get_participant_activity`
- **说明**：跨工具查询即将过期/进行中的活动。来源：抖店页面接口

### 多件满减

#### 创建多件立减

- **请求**：`POST /marketing/activity/v1/create_multi_piece_discount_activity`
- **说明**：创建「同品多件优惠（多件立减）」活动。体：{ multi_item_discount_activity: { activity_product（只 1 个商品）, activity_type（1第二件半价 2第二件0元 3自定义第N件）, discount_type（预设玩法固定 1；自定义时 1打折/3立减）, discounts（预设玩法传空数组 []）, start_time, end_time } }。⚠️ 与「创建多件满减活动」是**两条不同路径**（那条是满 N 件优惠）。用 云捷.营销.满减.创建多件立减()。来源：抖店页面接口

### 活动查询

#### 查询商品参与活动

- **请求**：`POST /marketing/common/v1/get_common_conf`
- **说明**：查询某个商品参与了哪些活动（活动互斥排查）。来源：抖店页面接口

### 多件满减

#### 查询多件立减

- **请求**：`GET /marketing/activity/v1/query_multi_piece_discount_activity`
- **说明**：查询多件立减（同品多件优惠）活动。默认 **GET + 查询参数**（page/pageSize/product_id/activity_status/start_time/end_time，与平台页面一致）；传平台英文键的请求体或 请求方式:'POST' 走旧的 POST 透传。返回 data 直接是数组（activity_id / activity_product / activity_status）。用 云捷.营销.满减.查多件立减()。来源：抖店页面接口

### 赠品活动

#### 赠品活动-可选主品/可选赠品

- **请求**：`POST /marketing/activity/v1/query_available_product_v2`
- **说明**：赠品活动的「加载商品 / 选择赠品 / 创建前刷库存」都用它（activityToolType=23、activitySubType={gift_sub_type:1}；product_type 0 主品 / 1 赠品）。能参加的在 data[]，带 reject_msg 的 = 不能参加（界面「已过滤商品」）；available_apply_num = 赠品可用库存。用 云捷.营销.赠品活动.可选商品() / 云捷.营销.赠品活动.可选赠品()。来源：抖店页面接口

### 活动查询

#### SKU促销价

- **请求**：`POST /marketing/riskcontrol/v1/sku_promotion_price`
- **说明**：查询SKU的促销价格（风控校验）。来源：抖店页面接口

#### SKU促销信息列表

- **请求**：`GET /marketing/promotion_query/v1/promotion_sku_list`
- **说明**：查询SKU维度的促销信息列表。来源：抖店页面接口

### 商品

#### 商品列表/搜索商品ID

- **请求**：`GET /product/tproduct/list`
- **说明**：查询店铺商品列表（支持按ID/名称/SKU编码搜索、销量排序）。**达人测评的「商品列表」也是这个路径**（用 云捷.商品.测评商品列表()）：固定 business_type=4、_bid=ffa_goods、is_online=1、pageSize=20、page 从 0 开始，「加载未开启」带 tag_code_and_val=is_product_talent_evaluation_close#1 + status=-1，「导入商品ID」带 id_name_code（逗号分隔，每批 ≤20）；返回行里 tab=商品状态、is_product_talent_evaluation_close=true 表示已关闭测评。写/查询口径：URL 不补 `_`/`s`（补了判「当前环境存在风险」）。**组件库「SKU搜索」的加载方式也走这条路径**（加载全部 / 售卖中 / 已下架 / 自定义筛选 / SKU编码）：加载全部 = is_online=1 + from_mng=1；售卖中 = is_online=1 + sort=desc + order_field=audit_time + check_status=3；已下架 = is_offline=1 + order_field=offline_time；自定义筛选 = sku_price_min/sku_price_max（分）+ sell_num_min/sell_num_max + start_time/end_time（创建时间）+ audit_start_time/audit_end_time（上架）+ offline_start_time/offline_end_time（下架）+ freight_id（运费模板）；SKU编码 = tab=onSale + id_name_code + status=0 + not_for_sale_search_type=1。返回行里 comment_num=评价数、comment_good=好评数、comment_percent=好评率（百分数，如 94）—— 组件用它们直接显示「评价数量 / 好评率」两列。**「清理无流量」的 售卖中 / 已下架 / 导入商品ID（id_name_code，每批 ≤20）/ 自定义筛选 也都走这条路径**（用 云捷.商品.选品列表()，返回 `data` 直接是数组）。用 云捷.商品.列表() / 选品列表() / 无销量列表() / 回收站列表() / 测评商品列表()。来源：抖店页面接口

#### 商品/SKU详情Schema

- **请求**：`POST /product/tproduct/getSchema`
- **说明**：查询商品完整发布结构（含SKU、主图、类目属性）。来源：抖店页面接口

#### 批量上架商品

- **请求**：`POST /product/tproduct/batchLaunchProduct`
- **说明**：批量上架（一次最多20个，表单提交）。来源：抖店页面接口

#### 批量下架商品

- **请求**：`POST /product/tproduct/batchOffline`
- **说明**：批量下架（一次最多20个，表单提交）。用 云捷.商品.批量下架(标签ID, 商品ID数组)；清挖「清理无流量」的下架就是它。来源：抖店页面接口

### 新人礼金

#### 新人礼金选商品(搜索可参加的礼金商品)

- **请求**：`POST /marketing/union_allowance/v1/search_product`
- **说明**：新人礼金页「选商品」用它搜可参加的礼金商品（POST + 体，查询带 _bid=ecom_market_shop/appid=1）。用 云捷.营销.新人礼金.选商品()。来源：抖店页面接口

### 商品

#### 批量删除商品

- **请求**：`POST /product/tproduct/batchDelete`
- **说明**：批量删除商品（表单提交，进回收站）。用 云捷.商品.批量删除(标签ID, 商品ID数组)；清挖「清理无流量」的「下架并删除」用它。来源：抖店页面接口

#### 批量编辑商品(改运费模板/发货模式)

- **请求**：`POST /product/tproduct/batchEdit`
- **说明**：商品批量修改：改运费模板（freight_id）与改发货模式/发货时间（delivery_time_info）共用本接口，靠请求体区分，一次最多 50 个商品，返回逐条 code/msg。写接口：URL 带 appid/__token/_bid/_lid（**不要补 `_` 和 `s`**，否则判「当前环境存在风险」），verifyFp/fp 由客户端自动补。来源：抖店页面接口

#### 设置/取消定时开售

- **请求**：`POST /product/timing_sale/save`
- **说明**：设置定时开售（sale_start_time）或取消（is_cancel=true）。来源：抖店页面接口

#### 商品图片批量上传(裂变)

- **请求**：`POST /product/img/batchupload`
- **说明**：上传图片到抖店素材中心（multipart，字段名 image[0]）。来源：抖店页面接口（需工作页上传）

#### AI短标题生成(裂变)

- **请求**：`POST /product/tproduct/refetchSchema`
- **说明**：按类目/素材生成商品短标题（裂变场景）。来源：抖店页面接口

#### 详情图格式化(裂变)

- **请求**：`POST /product/prettify/formatPrettifyForProduct`
- **说明**：格式化商品详情图（裂变场景）。来源：抖店页面接口

### 评价有礼

#### 评价有礼活动列表

- **请求**：`POST /marketing/comment_gift/v1/list_comment_gift_activity`
- **说明**：评价有礼活动列表。体 {page, page_size}，查询带 _bid=ecom_market_shop/appid=1。用 云捷.营销.评价有礼.列表()。来源：抖店页面接口

### 商机中心

#### 商机商品列表

- **请求**：`POST /api/commop/business_chance_center/product/list`
- **说明**：查某商机下可报名的商品详情。体：{condition:{clue_id 商机ID, first_cid 一级类目ID, product_id 商品ID}, page:{current,page_size}, with_suggest_seo_title_words:true}。来源：抖店页面接口

#### 商机列表·关键词搜索

- **请求**：`POST /api/commop/business_chance_center/clue/mixed/real_time_list`
- **说明**：按关键词搜索商机列表（商机中心搜索页那份实时商机）。体：{condition:{clue_info 关键词, categories:[{}] 类目, include_hot_sales_products}, mixed_clue_page:{page_size,current,offset}, terminal_type:0, source:'business_center'}；返回 data.mixed_clue_data.clue_list。来源：抖店页面接口（真机抓包）

### 评价有礼

#### 当前生效的评价有礼活动

- **请求**：`GET /marketing/comment_gift/v1/get_current_comment_gift`
- **说明**：当前生效的评价有礼活动（含活动信息 + comment_gift_coupon_list 券与商品明细）。用 云捷.营销.评价有礼.当前活动()。来源：抖店页面接口

### 商机中心

#### 商机线索详情

- **请求**：`POST /api/commop/business_chance_center/clue/detail`
- **说明**：查商机（线索）详情。体：{clue_channel:'', clue_id 商机ID, show_new_supply_link:true}。来源：抖店页面接口

### 商品

#### 读取商品库存(SKU)

- **请求**：`POST /stock/manage/detail`
- **说明**：读取商品各 SKU 的库存。体：{product_id 商品ID, source:'pc'}。返回 data.sku_detail_list[]：sku_id / sku_code(商家编码) / sku_name / sku_img / total_stock_num(**总库存**) / total_occupied_stock_num(已占用) / stock_type / status / spec_list / spec_map，以及 forbid_edit(当前能否改库存) / forbid_edit_reason。来源：抖店页面接口

### 评价有礼

#### 评价有礼页面基础配置

- **请求**：`GET /marketing/comment_gift/v1/query_base_info`
- **说明**：评价有礼页面的基础配置（设置方式、托管上限等）。来源：抖店页面接口

### 商机中心

#### 商机批量提交

- **请求**：`POST /api/commop/business_chance_center/multiple_item_submit/submit`
- **说明**：把商品详情批量提交（报名）到某个商机。体：{clue_id, products:[商品详情(用商品列表接口查出来原样传)], terminal_type:0, source:'business_center', module:'search_page_all', scene:''}。⚠️ 不要带 _bid/appid/_/s，否则被判环境风险返回滑块。来源：抖店页面接口

### 商品

#### 修改商品库存(SKU)

- **请求**：`POST /stock/manage/edit`
- **说明**：按 SKU 改库存。体：{stock_list:[{sku_id, stock_base_num(原库存), stock_incr_num(增量，可负), product_id}], scene:'商品管理页-编辑库存', appid:1} —— **最终库存 = 原库存 + 增量**，所以要先读库存当基准；用 SDK 云捷.商品.设置库存() 可自动读原库存算增量（云捷.商品.改库存() 是底层直传）。返回 { code:0, data:null }。来源：抖店页面接口

### 评价有礼

#### 评价有礼奖励金余额/预算

- **请求**：`GET /marketing/comment_gift/v1/query_comment_gift_balance`
- **说明**：奖励金余额与预算。返回 data.balance / deposit_account_balance / shop_account_balance / daily_budget（单位分）。来源：抖店页面接口

### 商机中心

#### 商机中心列表

- **请求**：`POST /api/commop/business_chance_center/item_submit/common/list`
- **说明**：查询商机中心报名记录 / 可报名商机。来源：抖店页面接口

### 评价有礼

#### 创建/编辑评价有礼活动

- **请求**：`POST /marketing/comment_gift/v1/create_edit_comment_gift`
- **说明**：创建与编辑是同一个接口（体里带 activity_id 就是编辑；查询 _bid=ecom_market_shop/appid=1）。体（平台原样，最外层包一层 activity）：{ activity: { activity_type: 43, title（前缀或「评价有礼」+ 3 位随机字符 + YYYYMMDDHHmm）, begin_time（秒级时间戳，取所选日期 00:00:00）, black_goods_list: [{product_id}], comment_gift_coupon_list: [{ credit（每张券金额·分）, goods_list: [{ product_id, order_cnt_30d（近30日累计销售）, total_valuable_comment_cnt（累计详评） }] }], config: { mode（1 智能管理 / 0 关闭）, setting（0 固定面额 / 1 自定义面额）, daily_budget（每日预算·分） } } }；成功 code=0 且 data.activity_id 有值；平台限制一个店铺只允许一个评价有礼活动、固定面额一次最多 50 个商品。用 云捷.营销.评价有礼.提交()。来源：抖店页面接口

### 评价

#### 商品评价列表

- **请求**：`GET /product/tcomment/commentList`
- **说明**：查询商品评价列表（可按星级、图片、回复状态等筛选）。来源：抖店页面接口

### 评价有礼

#### 停用评价有礼活动

- **请求**：`GET /marketing/comment_gift/v1/disable_comment_gift`
- **说明**：停用（结束）评价有礼活动。查询 _bid=ecom_market_shop/appid=1/activity_id（传 请求方式:'POST' 走旧的 POST + 体口径）。用 云捷.营销.评价有礼.停用()。来源：抖店页面接口

### 评价

#### 批量回复评价

- **请求**：`POST /product/tcomment/shopBatchReply`
- **说明**：批量回复买家评价。来源：抖店页面接口

### 评价有礼

#### 评价有礼活动效果数据

- **请求**：`GET /marketing/marketing_data/v1/query_promotion_data`
- **说明**：「查看效果」的活动数据。查询 source_type=8（评价有礼）/date_type（1 累计、2 今日）/activity_id；返回 data.stats_data{指标键: {field_name, val:{val, val_type}}}，val_type=2 是金额（分）。用 云捷.营销.评价有礼.效果数据()。来源：抖店页面接口

### 评价

#### 商品分析(质量退款/评价分析)

- **请求**：`POST /governance/shop/experiencescore/getDetailList`
- **说明**：商品体验分明细：质量退款分析（10301）/ 评价分析（10801）。来源：抖店页面接口

### 评价有礼

#### 营销工具授权状态

- **请求**：`GET /marketing/common/v1/tool_auth`
- **说明**：查店铺是否开通某个营销工具（查询 activity_type：43 评价有礼）。用 云捷.营销.评价有礼.工具授权()。来源：抖店页面接口

### 售后

#### 售后单详情

- **请求**：`GET /v1/aftersale/pc/detail`
- **说明**：查询售后单详情（after_sale_id）。来源：抖店页面接口

### 赠品活动

#### 赠品活动列表

- **请求**：`POST /marketing/pc/v1/gift_activity/list`
- **说明**：赠品活动列表（页面口径：POST + 请求体 activity_name/status/main_product_id/activity_code_list/page/size/activity_group，空名称与空商品ID 不传；查询带 _bid=ecom_market_shop&from_platform=pc&appid=1）。用 云捷.营销.赠品活动.列表()（传 请求方式:'GET' 可回到旧的 GET 口径）。来源：抖店页面接口

### 售后

#### 售后物流查询

- **请求**：`GET /shopuser/aftersale/logistics`
- **说明**：查询售后单的物流信息。来源：抖店页面接口

### 赠品活动

#### 赠品活动提交前校验

- **请求**：`POST /marketing/pc/v1/gift_activity/check`
- **说明**：创建赠品活动前的校验（查询带 _bid=ecom_market_shop&from_platform=pc&appid=1）。⚠️ 请求体与「创建」完全同一份，且最外层要包一层 gift_activity：{ gift_activity: {...} }。用 云捷.营销.赠品活动.校验()。来源：抖店页面接口

### 售后

#### 查询退货包裹物流轨迹

- **请求**：`GET /shopuser/power/queryReturnPackage`
- **说明**：查询退货包裹的物流轨迹。来源：抖店页面接口

### 赠品活动

#### 创建赠品活动

- **请求**：`POST /marketing/pc/v1/gift_activity/create`
- **说明**：创建赠品活动（主品 + 赠品 + 门槛 + 时间；查询带 _bid=ecom_market_shop&from_platform=pc&appid=1）。⚠️ 体 = { gift_activity: { activity_info, activity_time, activity_common_config, activity_rule, activity_product_list, gift_extra_config } }。用 云捷.营销.赠品活动.创建()。来源：抖店页面接口

### 售后

#### 创建售后导出任务

- **请求**：`POST /shopuser/aftersale/export`
- **说明**：创建售后数据导出任务（按申请时间区间），返回 task_id。来源：抖店页面接口

### 赠品活动

#### 停用活动(赠品等通用)

- **请求**：`POST /marketing/pc/v1/common/disable_activity`
- **说明**：停用活动（赠品活动等通用，体 { activity_group: 'GiftActivity', activity_id, campaign_id }；只有未开始/进行中可停用）。用 云捷.营销.赠品活动.停用()。来源：抖店页面接口

### 售后

#### 查询售后导出任务

- **请求**：`GET /shopuser/aftersale/export/tasks`
- **说明**：查询售后导出任务进度（status 1导出中 2可下载）。来源：抖店页面接口

### 惊喜券

#### 惊喜券活动列表

- **请求**：`GET /marketing/precision_promotion/v1/get_precision_promotion_instances`
- **说明**：惊喜券（人群营销）活动列表。查询 status（1处理中 2未开始 3生效中（默认）4已过期 5已作废）/page/page_size/search_key/start_time/end_time/biz_groups（0全部 1新客 2老客 3流失 4其他）；返回 data.instances[]。用 云捷.营销.惊喜券.列表()。来源：抖店页面接口

### 售后

#### 退货策略列表

- **请求**：`GET /shopuser/tshopuser/listAftersaleStrategy`
- **说明**：查询退货策略列表（每页最多10条）。来源：抖店页面接口

### 惊喜券

#### 惊喜券活动详情

- **请求**：`GET /marketing/precision_promotion/v1/get_precision_promotion_instance`
- **说明**：惊喜券活动详情（查询 activity_id）。用 云捷.营销.惊喜券.详情()。来源：抖店页面接口

### 售后

#### 退货策略详情

- **请求**：`GET /shopuser/tshopuser/getAftersaleStrategy`
- **说明**：查询退货策略详情（strategy_id）。来源：抖店页面接口

### 惊喜券

#### 惊喜券可用模板

- **请求**：`GET /marketing/precision_promotion/v1/get_precision_promotion_templates`
- **说明**：建惊喜券前先取可用模板。用 云捷.营销.惊喜券.模板()。来源：抖店页面接口

### 售后

#### 创建退货策略

- **请求**：`POST /shopuser/tshopuser/addAftersaleStrategy`
- **说明**：创建退货策略（关联退货地址与商品）。来源：抖店页面接口

### 惊喜券

#### 创建惊喜券活动

- **请求**：`POST /marketing/precision_promotion/v1/create_precision_promotion`
- **说明**：创建惊喜券活动（人群 + 券 + 时间，体为平台原样字段）。用 云捷.营销.惊喜券.创建()。来源：抖店页面接口

### 售后

#### 编辑退货策略

- **请求**：`POST /shopuser/tshopuser/updateAftersaleStrategy`
- **说明**：编辑退货策略（改名/换地址/增删关联商品）。来源：抖店页面接口

### 惊喜券

#### 停用惊喜券活动

- **请求**：`POST /marketing/precision_promotion/v1/disable_precision_promotion`
- **说明**：停用惊喜券活动（体带 activity_id）。用 云捷.营销.惊喜券.停用()。来源：抖店页面接口

### 售后

#### 识别售后地址

- **请求**：`GET /shopuser/tshopuser/recognizeAddress`
- **说明**：识别收货地址文本（省市区街道+姓名电话）。来源：抖店页面接口

#### 发送退货地址验证码

- **请求**：`GET /common/index/sendcode`
- **说明**：给退货地址手机号发送验证码。来源：抖店页面接口

#### 创建退货地址

- **请求**：`POST /shopuser/tshopuser/addAfterSales`
- **说明**：创建退货地址（表单提交，需手机验证码）。来源：抖店页面接口

#### 发货/退货地址列表

- **请求**：`GET /shopuser/tshopuser/getAfterSaleList`
- **说明**：查询地址库列表（分页：page/pageSize/keyword/sort/abnormal_address/appid，需 _bid=ffa_order）。返回 data.address_list[].id/user_name/mobile/address/detail/省市区街道/after_sale_note 等，另有 default_address、normal_address_count。**发货场景**（云捷.发货.发货地址列表）同路径，多带 source=send_deliver + sort=2、每页默认 50。来源：抖店页面接口

### 订单

#### 订单详情

- **请求**：`GET /api/order/orderDetail`
- **说明**：查询订单详情（order_id）。来源：抖店页面接口

#### 订单物流查询

- **请求**：`GET /api/order/getOrderLogistics`
- **说明**：查询订单物流信息。来源：抖店页面接口

### 售后

#### 删除退货策略

- **请求**：`POST /shopuser/tshopuser/delAftersaleStrategy`
- **说明**：删除退货策略（JSON 体：strategy_id；查询与体都要带 appid=1、_bid=ffa_order，写接口建议带 __token=云捷.取店铺令牌(店铺ID)）。策略绑着商品/是默认策略时删不掉，失败原因在 msg 或 data.fail_reason。来源：抖店页面接口

#### 删除退货地址

- **请求**：`POST /shopuser/tshopuser/delAfterSales`
- **说明**：删除退货地址（**表单提交**：id + version；version 用列表里该条的 version，做乐观锁）。带 data.block=true 表示地址被占用（如默认发货地址）删不掉，原因在 data.fail_reason.message。来源：抖店页面接口

### 订单

#### 订单实付价查询

- **请求**：`GET /marketing/promotion_query/v1/promotion_order_list`
- **说明**：查询订单成交价（到手价，含各类优惠）。来源：抖店页面接口

#### 订单发票列表

- **请求**：`GET /order/invoice/list`
- **说明**：查询订单发票列表。来源：抖店页面接口

### 运费模板

#### 运费模板详情/列表

- **请求**：`GET /freight/template/getShopFreightTemplate`
- **说明**：查询运费模板列表或详情（带 freight_id 即详情）。来源：抖店页面接口

#### 创建运费模板

- **请求**：`POST /freight/template/createTemplate`
- **说明**：创建运费模板（含发货地、运费规则）。来源：抖店页面接口

#### 更新运费模板

- **请求**：`POST /freight/template/updateTemplate`
- **说明**：更新运费模板。来源：抖店页面接口

#### 关闭中转物流

- **请求**：`POST /api/ls/close`
- **说明**：关闭新疆中转物流服务（创建/编辑模板前先关闭，避免报错）。来源：抖店页面接口

### 店铺治理

#### 违规罚单列表

- **请求**：`POST /governance/shop/penalty/v3/get_ticket_list`
- **说明**：查询店铺违规/罚单列表。来源：抖店页面接口

### 商品

#### 创建商品(发布提交)

- **请求**：`POST /product/tproduct/addWithSchema`
- **说明**：商品发布的提交接口（新建商品）。体是抖店原样的完整发布 Schema（参考项目内 接口管理/创建商品接口/ 的数据包）。用 云捷.商品.发布保存()。来源：抖店页面接口

### 店铺治理

#### 违规罚单详情

- **请求**：`POST /governance/shop/penalty/v3/get_ticket_detail`
- **说明**：查询违规/罚单详情（ticket_id）。来源：抖店页面接口

### 运费模板

#### 删除运费模板

- **请求**：`POST /freight/template/deleteFreightTemplate`
- **说明**：删除运费模板（**表单提交**：template_id）。成功时内层 data.msg='运费模板删除成功'；失败原因也在内层 data.msg。来源：抖店页面接口

### 商品

#### 保存商品编辑(编辑提交)

- **请求**：`POST /product/tproduct/editWithSchema`
- **说明**：抖店商品编辑页的提交接口，**编辑时必须带 product_id**；请求体与「创建商品」同一套 Schema（改哪个字段传哪个）。拿当前值先 云捷.商品.详情() 取完整 Schema，本地改完原样提交。用 云捷.商品.编辑保存()。来源：抖店页面接口

### 店铺治理

#### 拉取店铺赔付单

- **请求**：`POST /governance/shop/penalty/get_compensation_list`
- **说明**：按创建时间区间拉取赔付单。来源：抖店页面接口

### 商品

#### SKU规格价格 / 在售商品预览

- **请求**：`GET /product/tproduct/previewOnline`
- **说明**：一个路径两种用途：① 传商品ID 取 `data.spec_prices[].price`（分）与 `data.specs`（**列表接口里没有 SKU 价格/规格**，做低价引流这类判定要靠它，一次只能查一个商品）；② 在售商品预览链接。用 云捷.商品.SKU规格价格() / 云捷.商品.预览链接()。来源：抖店页面接口

### 店铺治理

#### 举报列表

- **请求**：`POST /shopuser/accuse/list`
- **说明**：查询举报记录列表。来源：抖店页面接口

### 商品

#### 商品能力开关查询

- **请求**：`GET /product/tproduct/isInAllowlist`
- **说明**：查商品能力开关（`list_name` 逗号分隔，如 can_add_prize=能否加赠品 / enable_stock_v2 / price_autofill）。做赠品、低价类功能前先查。用 云捷.商品.能力开关()。来源：抖店页面接口

### 店铺治理

#### 举报预检v2

- **请求**：`POST /shopuser/accuse/apply_pre_check_v2`
- **说明**：提交举报前先预检（校验这些订单能不能按该原因举报）。体：{scene_type（'report_type_unusual_comment' 异常评价 / 'report_type_unusual_chat' 异常会话 / 'report_type_unusual_order' 异常下单）, sub_scene_type（**举报原因编码**，必填）, sku_order_ids:[订单ID], accuse_id?}。返回 data.sku_orders_check_res{订单ID:提示}（有提示=不可举报）。⚠️ sub_scene_type 必须传**平台英文编码**，传中文会报「请先填写举报原因编码」；SDK 云捷.店铺.举报预检/举报原因列表 已内置中文↔编码对照（异常评价 9 条 + 异常会话 1 条）。来源：抖店页面接口

### 商品

#### 商品整改信息

- **请求**：`GET /product/tproduct/rectifyInfo`
- **说明**：商品列表页顶部的待优化/整改提示（查询 need_first_check=true；低价引流等问题会在这里出现）。用 云捷.商品.整改信息()。来源：抖店页面接口

### 店铺治理

#### 提交举报

- **请求**：`POST /shopuser/accuse/apply`
- **说明**：提交举报（异常评价 / 异常会话 / 异常下单）。体：{scene_type, sub_scene_type（**举报原因编码**，见下方对照）, report_desc（举报描述）, is_chat_granted（是否授权聊天记录）, sku_order_id（订单ID）, order_ids:[], proof_infos:[], come_from（默认 fxg_pc_comment_center）}。返回 data.id=举报ID。举报原因对照（sub_scene_type）：1 评价内容非交易商品或内容无意义=report_reason_evaluate_product_other_shop；2 评价等级为差评内容为好评=report_reason_fake_negative_comment；3 消费者买错型号=report_reason_wrong_size；4 评价内容中包含辱骂或不当词汇=report_reason_low_politics_guns；5 评价内容包含广告信息=report_reason_evaluate_advertise；6 订单签收前评价商品质量问题=report_reason_before_signing_evaluate；7 利用中差评骗赔=report_reason_negative_comment_compensation；8 同行恶意竞争=report_reason_business_evil_compete；9 平台发券导致的降价差评=report_reason_platform_voucher；10 发送无意义刷屏信息（异常会话）=report_reason_unusual_chat_7。用 SDK 时可直接传 序号 / 中文名 / 编码（云捷.店铺.举报原因列表）。来源：抖店页面接口

### 商品

#### 批量修改SKU

- **请求**：`POST /product/tproduct/modifySku`
- **说明**：批量改 SKU（价格 / 商家编码 / 规格等），体为平台原样字段（查询 _bid=ffa_goods/appid=1）。用 云捷.商品.批量改SKU()。来源：抖店页面接口

### 店铺经营

#### 店铺首页经营数据

- **请求**：`GET /pc/api/home/homepage`
- **说明**：查询店铺首页经营数据（成交、流量等）。来源：抖店页面接口

### 商品

#### 改库存(底层直传)

- **请求**：`POST /product/tproduct/updateStock`
- **说明**：按 SKU 改库存的底层接口（体为平台原样字段）。⚠️ 推荐用 云捷.商品.设置库存()（它会先读原库存再算增量）。用 云捷.商品.改库存底层()。来源：抖店页面接口

#### 价格校验(改价前)

- **请求**：`POST /product/tproduct/verifyPriceV2`
- **说明**：改价前校验是否违规/超范围（商品编辑页「保存」前会先调它）。URL 平台口径带 appid/__token/_bid=ffa_goods/_lid；返回 `verify_result === 'pass'` 才算通过，不通过时读 `hit_price_verify_rule_items[].tip_text`。体两种口径都收（平台原样 / 中文 SKU列表）。用 云捷.商品.价格校验()。来源：抖店页面接口

### 财务结算

#### 结算账户/资金信息

- **请求**：`GET /settlement/account/getAccountList`
- **说明**：查询店铺结算账户与资金信息。来源：抖店页面接口

### 商品

#### 商品分组/标签列表

- **请求**：`GET /product/tproduct/getProductGroupList`
- **说明**：商品分组（标签）列表，用于下拉（查询 pageSize，默认 100）。返回 data 即分组数组（group_id / group_name）。用 云捷.商品.分组列表()。来源：抖店页面接口

### 财务结算

#### 店铺主体列表

- **请求**：`GET /shop/be/bic/subjectChangeList`
- **说明**：查询店铺经营主体列表。来源：抖店页面接口

### 商品

#### 店铺发货时效规则

- **请求**：`GET /product/tproduct/getShopShipDelayRule`
- **说明**：店铺默认发货时效（仅展示用）。⚠️ 与「平台发货时效规则」（getPlatformDelayRule）不是同一条。用 云捷.商品.发货时效规则()。来源：抖店页面接口

### 财务结算

#### 店铺账单查询

- **请求**：`POST /bill_center/domestic/shop/query_item`
- **说明**：查询店铺账单明细。来源：抖店页面接口

### 商品

#### 平台发货时效规则

- **请求**：`GET /product/tproduct/getPlatformDelayRule`
- **说明**：平台层面的发货时效规则。用 云捷.商品.平台发货规则()。来源：抖店页面接口

### 快递拦截

#### 拦截单列表

- **请求**：`GET /api/ls/pageServiceOrder`
- **说明**：查询快递拦截单列表（分页：page/pageSize，serviceCode=SVC-WBHOLDUP）。返回 data.list[]：waybillNo(运单号)/express(快递编码)/orderNo/aftersaleId/interceptedTime(秒)/interceptedStatus(如 RETURN_SUC)/interceptedFeeStatus(INTERCEPTED_NO_FEE 不收费 / INTERCEPTED_FEE_WAIT 待收 / INTERCEPTED_FEE_SUC 已收)/interceptedFee(拦截费·分)/packageStatus/initiatorName/strategyDesc。抓包 URL 带 verifyFp/fp，用 SDK 云捷.拦截 调用（客户端自动补）。来源：抖店页面接口

### 商品

#### 各状态商品数

- **请求**：`GET /product/tproduct/aggsProductCount`
- **说明**：商品列表页顶部的概览数字（查询 tab 可选）。返回 data = {onsale, audit, unpass, forbidden, sell_out_new, draft}（键名以平台返回为准）。用 云捷.商品.状态统计()。来源：抖店页面接口

### 素材AI

#### 平台推荐素材图

- **请求**：`POST /doudian/ai/same_pic/recommend_pic`
- **说明**：平台推荐素材图（同款图推荐）。来源：抖店页面接口

### 快递拦截

#### 查看拦截物流轨迹

- **请求**：`POST /api/ls/service/queryTrackRouteInfo`
- **说明**：按运单号查看物流轨迹（体：{trackInfo:{trackNo 运单号, express 快递编码如 yuantong}}）。返回 data.RouteNodeList[]（Content 文案 / Timestamp 秒 / State / StateDescription）、TrackInfo、logisticsInfo、packageInfo。来源：抖店页面接口

### 商品

#### 类目列表

- **请求**：`GET /product/tproduct/categoryOptionsN`
- **说明**：取类目（cid=0 取一级类目，父类目ID 取下一级）；把商品里的 first_cid/second_cid/third_cid 翻成类目名。返回 data = [{id, name}]。用 云捷.商品.类目列表()。来源：抖店页面接口

### 素材AI

#### AI好图复刻提交生成任务

- **请求**：`POST /product/tproduct/material/imageTextVideo/submitImgOptimizeTask4PC`
- **说明**：提交 AI 好图复刻生成任务。来源：抖店页面接口

### 快递拦截

#### 拦截费明细

- **请求**：`GET /api/sc/intercept/settlement/QuerySettlementList`
- **说明**：查询拦截费结算明细（分页：page/pageSize/bizCodes=EXPRESS-INTERCEPT/feeCategoryId=10）。返回 data.list[]：logisticsNo/orderId/feeName/settlementAmount(结算金额·分)/settlementYuanAmount(元)/payerName/bizTime/settleTime/status。来源：抖店页面接口

### 商品

#### 彻底删除商品(回收站)

- **请求**：`POST /product/tproduct/completeDelete`
- **说明**：回收站里的「彻底删除」（不可恢复）。体 {product_ids:[商品ID]}。用 云捷.商品.彻底删除()。来源：抖店页面接口

### 素材AI

#### AI好图复刻查询生成任务

- **请求**：`POST /product/tproduct/material/imageTextVideo/queryImgOptimizeTask4PC`
- **说明**：查询 AI 好图复刻任务结果。来源：抖店页面接口

### 申诉中心

#### 售后申诉列表

- **请求**：`POST /governance/shop/appeal/get_list`
- **说明**：查询申诉列表（售后/违规共用一个接口）。体：{appeal_status(状态码，20=待申诉，-99=全部), scene_name('aftersale' 售后 / 'governance' 违规), shop_id_list:[抖店店铺ID], page, page_size, source_platform:6}。返回 data.appeal_info_list[]：appeal_id / business_id(查详情与提交申诉要用它) / appeal_status / operations / appeal_biz_info(被申诉业务，含 appeal_scene_cn / aftersale_reason 等)。来源：抖店页面接口

### 商品

#### 恢复商品(回收站还原)

- **请求**：`POST /product/tproduct/batchRecover`
- **说明**：把回收站里的商品恢复上架。体 {product_ids:[商品ID]}。用 云捷.商品.恢复商品()。来源：抖店页面接口

### 申诉中心

#### 申诉详情

- **请求**：`POST /governance/shop/appeal/detail`
- **说明**：查询申诉详情。体：{scene_name, business_id(列表里的 business_id), with_op_log:true, with_flow_node:true}。返回 data.against_detail(被申诉的售后单：aftersale_id / aftersale_reason / product_card / sku_order)、content(申诉内容)、flow_nodes[](流程节点)、op_logs、appeal_limit_info(enable_submit 能否提交 / enable_revoke 能否撤销)。来源：抖店页面接口

### 商品

#### 给商品打标(内部标签)

- **请求**：`POST /product/tproduct/addProductTag`
- **说明**：给商品打内部标签（**达人测评的「开启/关闭测评」就是打这个接口**：tag_code=is_product_talent_evaluation_close，tag_val `0`=开启 / `1`=关闭，一次 ≤20 个）。返回 `{code, data:{failed_product_ids}}` —— 在 failed_product_ids 里的就是没打成功的。写接口口径：URL 带 appid/__token/_bid/_lid 且**不补 `_`/`s`**，请求体重复带这 4 个参数，**URL 的 `_lid` 与请求体的 `_lid` 是两个不同的值**（各生成一次）。用 云捷.商品.打标签()。来源：抖店页面接口

### 申诉中心

#### 读取申诉原因

- **请求**：`POST /governance/shop/appeal/rule`
- **说明**：读取某场景下可选的申诉原因（提交申诉前先调它拿 reason_id）。体：{scene_name:'aftersale', scene_type(申诉类型，如 QUALITY_ISSUE_REFUND_ONLY / LOGISTICS_RETURN，取自申诉详情 data.scene_type), rule_id}。返回 data.reasons[]：reason_id(提交申诉的 appeal_reason_id) / reason(原因文案) / reason_spec / sample_link / must_proof / guides[]；data.rule_spec 是举证与次数限制（appeal_times_limit 等）。来源：抖店页面接口

### 商品诊断

#### 诊断总览

- **请求**：`GET /product_diagnose/tproduct/get_diagnose_task`
- **说明**：商品诊断总览（待优化商品数 / 问题数 / 达标率）。用 云捷.商品诊断.总览()。来源：抖店页面接口

### 申诉中心

#### 提交申诉

- **请求**：`POST /governance/shop/appeal/submit`
- **说明**：提交售后/违规申诉（售后用 SDK 云捷.申诉.提交申诉，场景传 'aftersale'）。体：{scene_name, scene_type, business_id, rule_id, business_ids:[...], source_platform:1, appeal_content:{appeal_reason_id(申诉原因ID), appeal_reason(原因文案), reason(申诉说明), phone_num(联系电话), proof:[凭证图URL]}}。返回 data.data[业务ID] = 新建的申诉ID。来源：抖店页面接口

### 商品诊断

#### 诊断商品列表

- **请求**：`GET /product_diagnose/tproduct/get_diagnose_product_list`
- **说明**：诊断商品列表（可按瓶颈/问题筛选）。用 云捷.商品诊断.商品列表()。来源：抖店页面接口

#### 问题工具列表

- **请求**：`GET /product_diagnose/tproduct/get_diagnose_optimized_tool`
- **说明**：诊断的问题工具列表（带 problem_codes）。用 云捷.商品诊断.工具列表()。来源：抖店页面接口

#### 某类问题下的商品明细

- **请求**：`POST /product_diagnose/tproduct/get_diagnose_optimize_result`
- **说明**：按某类问题（problem_code）取商品明细。用 云捷.商品诊断.明细()。来源：抖店页面接口

#### 提交商品优化

- **请求**：`POST /product_diagnose/tproduct/submit_diagnose_optimize`
- **说明**：提交优化（走规则库确认后的口径）。用 云捷.商品诊断.提交优化()。来源：抖店页面接口

#### 属性自动优化托管状态

- **请求**：`GET /product_diagnose/tproduct/get_prop_auto_opt_shop_benefit`
- **说明**：属性自动优化的托管状态/收益。用 云捷.商品诊断.属性托管()。来源：抖店页面接口

#### 标题SEO自动优化状态

- **请求**：`GET /product_diagnose/tproduct/get_title_seo_auto_opt_shop_status`
- **说明**：标题 SEO 自动优化的托管状态。用 云捷.商品诊断.标题托管()。来源：抖店页面接口

### 素材AI

#### 推荐商品标题(按图片)

- **请求**：`POST /product/tproduct/getRecommendTitle`
- **说明**：根据已上传的图片 URL 生成推荐商品标题。体：{img_url 图片地址, action_type:'auto'}。返回 data.recommend_titles / recommend_titles_v2。来源：抖店页面接口

#### 预测商品类目(图片+标题)

- **请求**：`POST /product/tproduct/predictCategoryN`
- **说明**：按图片 + 标题预测商品类目。体：{scene:'predict_by_title_and_img', pic:[{url 图片地址}], title 标题, publish_id 店铺ID+时间戳, is_auction_or_mass:false}。返回 data.candidate_category_details / category_recommend_record_id。来源：抖店页面接口

### 发货

#### 待发货订单列表

- **请求**：`GET /api/order/searchlist`
- **说明**：查询待发货订单列表（「订单管理 → 待发货」页）。固定参数：page（**从 0 开始**）/ pageSize / order_status=stock_up / tab=stock_up / order_by=create_time / order=desc / compact_time[select]=create_time_start,create_time_end / source=shop_order_view_upgrade，URL 带 verifyFp/fp（客户端自动补）。返回 data[] = 订单行：shop_order_id（订单号）/ order_status / pay_amount(分) / exp_ship_time(最晚发货时间·秒) / receiver_info（收件人，已脱敏）/ product_item[]（子订单：item_order_id = **子订单号**，发货时当 productOrderId 用）。用 SDK 云捷.发货.待发货订单列表()。来源：抖店页面接口

#### 物流公司列表

- **请求**：`GET /api/order/query_logistics_company`
- **说明**：查询发货可选的物流公司（发货弹窗的下拉）。URL 带 appid/__token/_bid=ffa_order/aid=4272/_lid + verifyFp/fp。返回 data.all_logistics[]（按首字母 abbr 分组，组内 logistics_group[]：company_code（**发货要传的编码**）/ company_name / id / is_popular / need_telephone / need_tracking_no / need_rider_name）+ data.sort_all_logistics[]（同一份按拼音平铺）+ electronic_express_logistics / manual_express_logistics。用 SDK 云捷.发货.物流公司列表() 或 云捷.发货.物流公司()（已摊平成一维）。来源：抖店页面接口

#### 运单号识别快递公司

- **请求**：`GET /api/order/guess_logistics_company_by_tracking_no`
- **说明**：按运单号猜快递公司（发货页粘上单号后自动选）。查询 tracking_no=运单号 + appid/__token/_bid=ffa_order/aid=4272/_lid。返回 data[] = [{ company_code, company_name（可能带「(常用)」后缀）, tags }]。用 SDK 云捷.发货.识别快递公司()。来源：抖店页面接口

#### 发货检查

- **请求**：`POST /api/order/sendcheck`
- **说明**：发货前检查（平台用它决定「能不能发 / 要不要弹确认」）。体：{orderIds:[订单号], sendList:[{orderId, companyCode?, logisticsCode?, productItem:[{skuOrderId}]}], checkType, scene:'send', appid:1, __token, _bid:'ffa_order', aid:4272, _lid}；checkType **4**=打开发货页检查（只有订单号+子订单号）、**7**=填完运单号后检查（带 companyCode/logisticsCode）。返回 data：normalShopOrders（可发）/ withOutAftersalShopOrders（有未完结售后）/ doubleCheckNum + doubleCheckDetail[].title（**要展示给用户**，如「物流单号已被其它订单使用」）/ needSerialNoShopOrders / buttons（继续发货·取消）。用 SDK 云捷.发货.发货检查()。来源：抖店页面接口

#### 发货(提交运单号)

- **请求**：`POST /order/torder/batchsend`
- **说明**：批量发货：提交运单号把订单发出去（一次可多单）。体：{scene:'send', send_type:'1', send_list:[{order_id, company_code, logistics_code, productItem:[{productOrderId（=子订单号 item_order_id）, productCount, serial_numbers, serial_nos:{serial_no_list,status:1,status_desc:'未上传',is_show:true}}], package_no:0}], address_id（**发货地址 id**，来自发货地址列表）, delivery_source_page:'order_manage', appid:1, __token, _bid:'ffa_order', aid:4272, _lid}。返回 data.successList（**已发货订单号**）/ failedNum / failedList / sendFailList / sendFailListV2 / total / pop_window。发货前先调「发货检查」。用 SDK 云捷.发货.提交发货()。来源：抖店页面接口

### 运费模板

#### 运费模板列表(商品侧/下拉)

- **请求**：`GET /freight/template/getFreightTemplateList`
- **说明**：商品侧那份运费模板列表（用于「批量改运费模板」的下拉，**也是组件库「SKU搜索 → 自定义筛选」的运费模板下拉**）。查询 _a=1/appid=1/_bid=ffa_goods；返回 {list:[{id, template_name}]}（也兼容 data.list / data.template_list）。⚠️ 与「运费模板详情/列表」（getShopFreightTemplate）**不是同一条路径**，别混用。用 云捷.商品.运费模板列表() / 云捷.售后.运费模板列表简洁版()（「清理无流量」「低价引流检测」的自定义筛选也用它）。来源：抖店页面接口

## 飞鸽接口（按分组）

> 这些是「飞鸽」的接口，请用对应平台的 SDK 能力调用。

### 飞鸽数据-历史会话

#### 历史会话列表（搜索客服会话）

- **请求**：`POST /pcbackstage/fuzzySearchConversation`
- **说明**：**最值钱的一个接口**：历史会话列表，**含 chats[] 消息明细**（查询 PIGEON_BIZ_TYPE=2 & _pms=1；体含时间/客服/客户/会话ID/内容/场景等筛选）。用 云捷.飞鸽数据.历史会话()。来源：飞鸽数据

### 飞鸽-工作台

#### 查询订单

- **请求**：`GET /pcbackstage/getOrder`
- **说明**：飞鸽工作台：查会话关联的订单信息。来源：飞鸽（非店铺页面）

#### 工作台添加备注

- **请求**：`POST /pcbackstage/workshop/addRemark`
- **说明**：飞鸽工作台：给会话 / 订单添加备注。来源：飞鸽（非店铺页面）

#### 获取会话聊天记录

- **请求**：`POST /pcbackstage/get_history_msg_sub`
- **说明**：飞鸽工作台：拉某会话的聊天记录。来源：飞鸽（非店铺页面）

### 飞鸽数据-店铺数据

#### 店铺核心指标卡

- **请求**：`POST /pcbackstage/data/shop_core_data`
- **说明**：飞鸽「数据 → 店铺数据」核心指标卡（体 {is_offline:true, startDay, endDay}）。用 云捷.飞鸽数据.店铺核心()。来源：飞鸽数据

#### 店铺数据明细表

- **请求**：`POST /pcbackstage/data/shop_data_list_v2`
- **说明**：店铺数据明细表（**43 个指标**，体 {is_offline:true, startDay, endDay, listType:0}）。用 云捷.飞鸽数据.店铺明细()。来源：飞鸽数据

#### 店铺数据下钻

- **请求**：`POST /pcbackstage/data/shop_drill_data`
- **说明**：店铺数据下钻（意图 / 商品 / 评价 / 客服维度；体 {is_offline:true, start_day, end_day} —— ⚠️ 这两个是**下划线**）。用 云捷.飞鸽数据.店铺下钻()。来源：飞鸽数据

#### 下钻明细

- **请求**：`POST /pcbackstage/data/shop_drill_detail`
- **说明**：下钻后的明细表（体 {is_offline, startDay, endDay, page, page_size, first_intent, second_intent, list_type, indicator_type}）。用 云捷.飞鸽数据.店铺下钻详情()。来源：飞鸽数据

#### 下钻摘要文案

- **请求**：`POST /pcbackstage/data/shop_drill_top_data`
- **说明**：下钻顶部的一句话摘要（体 {startDay, endDay, indicator_type}）。用 云捷.飞鸽数据.店铺下钻摘要()。来源：飞鸽数据

#### 指标字典

- **请求**：`POST /pcbackstage/data/indicator_meta_info`
- **说明**：飞鸽数据指标的官方中文名与口径（**55 个指标**，体 {}）。用 云捷.飞鸽数据.指标字典()。来源：飞鸽数据

#### 报表表头

- **请求**：`GET /pcbackstage/getReportHeader`
- **说明**：数据报表的表头（查询 bizType：5 = 客服表现 / 7 = 店铺数据）。用 云捷.飞鸽数据.报表表头()。来源：飞鸽数据

### 飞鸽数据-客服数据

#### 客服表现（主表）

- **请求**：`GET /pcbackstage/queryStaffData`
- **说明**：客服表现主表 + 店铺平均（查询 page/size/queryType=1/startTime/endTime/_pms=1）。用 云捷.飞鸽数据.客服表现()。来源：飞鸽数据

#### 客服日志（上下线流水）

- **请求**：`GET /pcbackstage/queryStaffLog`
- **说明**：客服在线状态流水（查询 startTime/endTime/platformId=3/page/size）。用 云捷.飞鸽数据.客服日志()。来源：飞鸽数据

#### 客服权限

- **请求**：`GET /pcbackstage/getCustomerServiceAllPermission`
- **说明**：当前账号的客服数据权限（查询 biz_type=4 / PIGEON_BIZ_TYPE=2 / _pms=1）。用 云捷.飞鸽数据.客服权限()。来源：飞鸽数据

#### 店铺灰度开关

- **请求**：`GET /pcbackstage/shop/gray`
- **说明**：店铺灰度开关（与客服权限同参数）。用 云捷.飞鸽数据.灰度开关()。来源：飞鸽数据

### 飞鸽数据-历史会话

#### 历史会话筛选项字典

- **请求**：`GET /pcbackstage/fuzzySearchConversationConf`
- **说明**：历史会话页所有下拉的取值（场景 / 来源 / 意图字典）。用 云捷.飞鸽数据.历史会话筛选项()。来源：飞鸽数据

#### 机器人筛选项

- **请求**：`GET /pcbackstage/intelligence_robot/fuzzy_search_conversation_conf`
- **说明**：智能客服相关的筛选项字典。用 云捷.飞鸽数据.机器人筛选项()。来源：飞鸽数据

### 飞鸽数据-服务洞察

#### 服务问题概览

- **请求**：`GET /backstage/getServiceProblemData`
- **说明**：服务问题分析概览指标卡（查询 startDay/endDay）。用 云捷.飞鸽数据.服务问题概览()。来源：飞鸽数据

#### 服务问题趋势

- **请求**：`GET /backstage/getServiceProblemSessionTrend`
- **说明**：服务问题趋势（折线；查询 startDay/endDay/dimension=problem_type）。用 云捷.飞鸽数据.服务问题趋势()。来源：飞鸽数据

#### 服务问题分布

- **请求**：`GET /backstage/getServiceProblemSessionDistribution`
- **说明**：服务问题分布（饼图；参数同趋势）。用 云捷.飞鸽数据.服务问题分布()。来源：飞鸽数据

#### 服务问题会话明细

- **请求**：`POST /backstage/getServiceProblemServiceDetail`
- **说明**：某类服务问题下的会话明细（体 {startDay, endDay, page, pageSize, groupId:'-1'}）。用 云捷.飞鸽数据.服务问题明细()。来源：飞鸽数据

#### 服务问题类型配置

- **请求**：`GET /backstage/getConfig`
- **说明**：服务问题类型码表（查询 tcc_keys=serviceProblem）。用 云捷.飞鸽数据.服务问题配置()。来源：飞鸽数据

#### 告警规则

- **请求**：`GET /backstage/alert/optionalCustomRules`
- **说明**：服务问题告警规则（查询 scene=service_problem）。用 云捷.飞鸽数据.告警规则()。来源：飞鸽数据

#### 告警通知对象

- **请求**：`GET /backstage/alert/optionalNotifyList`
- **说明**：告警的通知对象列表。用 云捷.飞鸽数据.告警通知对象()。来源：飞鸽数据

#### 客服分组

- **请求**：`GET /backstage/data/groupQuery`
- **说明**：客服分组（查询 queryType=1 & biz_type=4 & PIGEON_BIZ_TYPE=2）。用 云捷.飞鸽数据.客服分组()。来源：飞鸽数据

#### 机器人配置

- **请求**：`GET /backstage/getRobot`
- **说明**：机器人配置（查询 shop_id）。用 云捷.飞鸽数据.机器人配置()。来源：飞鸽数据

### 飞鸽数据-消费者原声

#### 原声总量分布

- **请求**：`GET /backstage/getVocTotalDistribution`
- **说明**：消费者问题原声的总量分布（查询 start/end）。用 云捷.飞鸽数据.原声分布()。来源：飞鸽数据

#### 原声概览摘要

- **请求**：`GET /backstage/getMannerOrVocSummary`
- **说明**：原声概览摘要（查询 problem_type=voc、start、end、page、size、request_id=<店铺ID>-<起>-<止>、switch_to_human=1 —— request_id 由 SDK 自动拼）。用 云捷.飞鸽数据.原声概览()。来源：飞鸽数据

#### 原声按对象列表

- **请求**：`GET /backstage/getVocListByObject`
- **说明**：按对象（object_type：1 客服 / 2 商品）看原声列表。用 云捷.飞鸽数据.原声对象列表()。来源：飞鸽数据

#### 原声分析任务（轮询）

- **请求**：`GET /logifier/retrieval/tasks/poll`
- **说明**：平台 AI 任务调度器轮询（原声分析用；查询需 设备ID + 签名，签名由页面给）。用 云捷.飞鸽数据.原声分析任务()。来源：飞鸽数据

## 店管家接口（按分组）

> 店管家是**独立账号体系**（手机号+密码，与抖店店铺无关），这些接口**不能在「接口调试」里直接发**，请用 `云捷.店管家.*`。

### 店管家-登录

#### 协议登录

- **请求**：`POST /FFAccount/LoginPortal`
- **说明**：店管家登录（手机号+密码，base64 加密后提交，NotUseAliyunCaptcha=true 跳过滑块）。用 云捷.店管家.登录()。来源：店管家接口

#### 我的店铺列表

- **请求**：`POST /partner/LoadMyShopList`
- **说明**：当前店管家账号下的店铺列表。用 云捷.店管家.店铺列表()。来源：店管家接口

### 店管家-商品

#### 商品列表(全部商品/搜索)

- **请求**：`POST /Product/LoadList`
- **说明**：商品列表：标题模糊搜（InputProductName）、商品ID/货号可逗号多个。⚠️ 每个商品只带第一条 SKU。用 云捷.店管家.取商品列表()。来源：店管家接口

#### 商品规格明细(全量SKU)

- **请求**：`POST /Product/GetSettlementProductList`
- **说明**：按商品码取该商品的**全量 SKU（规格）**（body productCodes[] 重复同名键 + queryType=product）。用 云捷.店管家.取商品规格()。来源：店管家接口

#### 触发商品同步

- **请求**：`POST /Product/SyncProduct`
- **说明**：触发店管家同步抖店商品。用 云捷.店管家.同步商品()。来源：店管家接口

### 店管家-绑定厂家

#### 商品绑定厂家/自营(异步任务)

- **请求**：`POST /Product/TriggerBindSupplier`
- **说明**：商品绑定厂家或改自营；支持整商品或按规格（IsBindSku=true + skuCodes[商品码]=规格码,规格码）；一次最多 500 个商品。用 云捷.店管家.绑定厂家()。来源：店管家接口

#### 查绑定任务进度

- **请求**：`POST /Product/GetBindSupplierStatus`
- **说明**：查「绑定厂家」异步任务的进度（Status=5 表示无进行中任务）。用 云捷.店管家.绑定状态()。来源：店管家接口

#### 厂家列表(可搜索)

- **请求**：`POST /Partner/LoadMySupplierList`
- **说明**：厂家列表：key 搜索、status=0s、分页；返回 Id(厂家ID)/Remark(名称)/RemarkName(备注)。用 云捷.店管家.厂家列表()。来源：店管家接口

#### 修改厂家备注

- **请求**：`POST /Partner/EditSupplierRemark`
- **说明**：改厂家备注（id=厂家ID，remark=新备注，写的是 RemarkName）。用 云捷.店管家.修改厂家备注()。来源：店管家接口

### 店管家-订单

#### 订单列表(多条件查询)

- **请求**：`POST /NewOrder/List`
- **说明**：按时间/状态/供应商/SKU/店铺查订单（每页 500）。用 云捷.店管家.查订单()。来源：店管家接口

#### 今日各SKU出单量

- **请求**：`POST /NewOrder/LoadProductList`
- **说明**：今日各 SKU 订单数量（出单排行榜数据源）。用 云捷.店管家.SKU出单量()。来源：店管家接口

#### 按订单号查发货厂家

- **请求**：`POST /SendOrder/GetSendOrderHistorys`
- **说明**：查近 1 天的发货记录（发货厂家）。用 云捷.店管家.按订单号查发货厂家()。来源：店管家接口

### 店管家-售后

#### 触发售后单同步

- **请求**：`POST /AfterSale/TriggerSync`
- **说明**：拉售后前先触发一次同步，数据更准。用 云捷.店管家.同步售后单()。来源：店管家接口

#### 售后单列表

- **请求**：`POST /AfterSale/LoadAfterSaleList`
- **说明**：售后单列表（每页 500，可按订单号批量查）。用 云捷.店管家.拉取售后() / 按订单号查售后()。来源：店管家接口

### 店管家-结算

#### 保存商品/SKU简称与重量

- **请求**：`POST /Product/SaveShortTitleOrWeight`
- **说明**：写商品简称 / SKU 简称 / 重量。用 云捷.店管家.请求('/Product/SaveShortTitleOrWeight', 体)。来源：店管家接口

#### 设置SKU结算价

- **请求**：`POST /FinancialSettlement/SetProductSettlementPrice`
- **说明**：按 SKU × 厂家设置结算价（SettlementType=1、PlatformType=TouTiao）。用 云捷.店管家.请求('/FinancialSettlement/SetProductSettlementPrice', 体)。来源：店管家接口

## 精选联盟接口（按分组）

> 这些是「精选联盟」的接口，请用对应平台的 SDK 能力调用。

### 精选联盟-找达人

#### 当前用户/店铺（判登录态）

- **请求**：`GET /index/getUser`
- **说明**：当前登录用户与店铺。⚠️ **未登录时 code 也是 0** —— 用 `data.user_id === '0'` / `shop_name` 为空判断登录态。用 云捷.精选联盟.当前用户()。来源：精选联盟（巨量百应）

#### 筛选条件字典

- **请求**：`GET /square_pc_api/square/filter`
- **说明**：达人广场的筛选条件字典（类目 / 粉丝数 / 等级 / 带货数据…的 field_name + 可选值，返回 data.headers[]）。查询 type=1&req_scene=1。用 云捷.精选联盟.筛选条件()。来源：精选联盟（巨量百应）

#### 搜索建议词

- **请求**：`GET /square_pc_api/square/sug`
- **说明**：达人广场搜索框的下拉建议词（查询 query、sug_source=0）。用 云捷.精选联盟.搜索建议()。来源：精选联盟（巨量百应）

#### 达人列表（找达人）

- **请求**：`POST /square_pc_api/square/search_feed_author`
- **说明**：达人广场搜索。体 {page, refresh, type, query, search_id, filters}；⚠️ **filters 的值必须是数组**（filters 的 key = 筛选字典里的 field_name、值 = 它的 value）；返回 data.list[]，关键字段 author_base.uid（**加密串**，后面搜商品 / 发邀约都靠它）。⚠️ 必须 POST（GET 会返回 10001010A 环境风险）。用 云捷.精选联盟.找达人()。来源：精选联盟（巨量百应）

### 精选联盟-邀约带货

#### 能否沟通/发邀约

- **请求**：`GET /connection/pc/im/account_check`
- **说明**：判断这个达人能不能沟通 / 能不能发邀约。查询 account_id=<达人uid>、account_type=1、account_app_id=1128。用 云捷.精选联盟.能否沟通()。来源：精选联盟（巨量百应）

#### 邀约文案示例

- **请求**：`GET /connection/pc/im/invite/examples`
- **说明**：平台给的邀约文案示例（邀约弹窗「示例」按钮）。用 云捷.精选联盟.邀约文案示例()。来源：精选联盟（巨量百应）

#### 搜可邀约商品

- **请求**：`GET /connection/pc/im/promotion/list`
- **说明**：该达人**可带**的商品（未加入联盟推广的不显示）。查询 page_size=20、query（可空）、cursor=0、uid=<达人uid>；cursor 游标翻页 + data.has_more。返回 data.promotion_list[]（product_id / promotion_id / title / price(分) / cos_ratio / orient_cos_ratio_detail / sample）。用 云捷.精选联盟.搜可邀约商品()。来源：精选联盟（巨量百应）

#### 发送邀约卡片

- **请求**：`POST /connection/pc/im/invite/card/send`
- **说明**：⚠️ **会真的给达人发 IM**。体 {account_id（达人uid，不是抖音号）, account_type:1, invite_card:{content, rights:[{right:3}], product_ids, product_setting:[{product_id, author_sample_status, orient_cos_ratio_detail:{orient_kol_cos_ratio, time_radio:'long', valid_time, suggest_orient_kol_cos_ratio}}], is_open_feed}, contact_info:{phone, wechat}, event_param:{client_form:'pc'}, entry_point:1}；返回 data.msg_id / data.target_account / data.sample_failed_reason。⚠️ 平台限制：**首次邀约要按模板填、达人回复后才能继续发**；批量连发会被风控静默限流（空响应），每条间隔 2~5 秒、别并发。用 云捷.精选联盟.发邀约()。来源：精选联盟（巨量百应）

## 电商罗盘接口（按分组）

> 这些是「电商罗盘」的接口，请用对应平台的 SDK 能力调用。

### 电商罗盘-账号

#### 登录账号信息

- **请求**：`GET /ecomauth/loginv1/get_account_info`
- **说明**：罗盘登录账号（查询 login_source=compass）；`data.account_name` 为空 = 未登录。用 云捷.电商罗盘.登录账号()。来源：电商罗盘

### 电商罗盘-经营大盘

#### 单日核心指标

- **请求**：`GET /compass_api/shop/common/homepage/summary_core_index_v3`
- **说明**：单日核心指标（收入 / 成交 / 订单 / 退款 / 曝光 / 消耗…），返回 data.module_data 下的 homepage_core_index。用 云捷.电商罗盘.核心指标(标签ID, 日期)。来源：电商罗盘

#### 店铺同行排名

- **请求**：`GET /compass_api/shop/common/homepage/shop_rank`
- **说明**：店铺在同行中的排名。用 云捷.电商罗盘.店铺排名()。来源：电商罗盘

### 电商罗盘-数据

#### 数据范围（统计周期）

- **请求**：`GET /compass_api/config_center/data_range_v2`
- **说明**：查某个数据类型的可选统计周期（查询 data_type，如 shop_product_list）；返回**完整响应体** `{ code, data: { max_date, ... } }` —— ⚠️ **可用日期在 `data.max_date`（秒级时间戳 = 统计周期结束日，不是「今天」）**，不是顶层 max_date。用 云捷.电商罗盘.数据范围()（「清理无流量」的统计周期结束日就是它）。来源：电商罗盘

#### 商品列表导出

- **请求**：`GET /compass_api/download_center/shop/download_file_sync`
- **说明**：导出商品列表为 xlsx（查询 req_json_str，里面 date_type：近1天 20 / 近7天 21 / 近30天 23）。⚠️ **SDK 内已把 xlsx 解析成行数组**：返回 { 状态, 类型, base64, 行, 解析失败原因 }。用 云捷.电商罗盘.商品列表导出(标签ID, { 周期, 结束日期 })（「清理无流量」判无流量用的曝光/点击人数就是它导出来的）。来源：电商罗盘

## 巨量千川接口（按分组）

> 这些是「巨量千川」的接口，请用对应平台的 SDK 能力调用。

### 千川-账号与余额

#### 广告账户列表

- **请求**：`GET /ad/api/v1/account/user-list`
- **说明**：该店铺登录下挂的广告账户（返回 data.userAccountInfos，`id` 就是 **aavid**）。⚠️ 一个抖店登录常挂多个账户，**要让用户选**、结果由应用自己按「店铺ID」保存。用 云捷.千川.账户列表()（走客户端桥）。来源：巨量千川

#### 取广告账户ID(aavid)

- **请求**：`GET /ad/api/v1/account/user/access/check`
- **说明**：取当前可用广告账户 ID。查询 type=3、product_id=0、_lib=<随机串>；成功 `code === 0`，返回 data.aavid。用 云捷.千川.取aavid()。来源：巨量千川

#### 广告投放余额

- **请求**：`GET /cg_trade/finance/backend/finance/balance/v2`
- **说明**：千川**广告余额**（`totalValidBalance`，单位**元**、字符串）。⚠️ 与「抖店货款余额」不是同一个池子；财务接口成功码是 **`code === 1`**。用 云捷.千川.余额()。来源：巨量千川

#### 抖店货款余额

- **请求**：`GET /cg_trade/finance/backend/charge/getGoodsDirectInfo`
- **说明**：抖店**货款余额**（`goodsBalanceCent`，单位**分**）；参数名是 `aadvid`。用 云捷.千川.货款直投余额()。来源：巨量千川

#### 赠款余额

- **请求**：`GET /cg_trade/finance/backend/finance/grant/balance`
- **说明**：千川赠款余额（查询 type=3、aadvid、gfversion=1.0.1.8174；**成功码 code === 1**）。用 云捷.千川.赠款()。来源：巨量千川

### 千川-全域推广

#### 商品列表

- **请求**：`GET /ad/api/creation/v1/product/list-products`
- **说明**：全域推广/乘方创建计划时的可选商品。成功码看 `status_code === 0`。用 云捷.千川.全域推广.商品列表()。来源：巨量千川

#### 效果估算

- **请求**：`GET /ad/api/creation/v1/uni_prom/get-suggested-estimate`
- **说明**：按预算/ROI 估算效果（marGoal=1）。用 云捷.千川.全域推广.估算()。来源：巨量千川

#### 创意默认值

- **请求**：`GET /ad/api/creation/v1/config-manage/get-oeconfig-creation-link`
- **说明**：创建计划的创意默认值（取返回 cdnLink.creation 配置里的 procedureCreative.defaultValue）。用 云捷.千川.全域推广.创意默认值()。来源：巨量千川

#### 默认抖音号

- **请求**：`GET /ad/api/creation/v1/uni-prom-product/default-aweme-user`
- **说明**：该广告账户的默认抖音号。用 云捷.千川.全域推广.默认抖音号()。来源：巨量千川

#### 抖音号列表

- **请求**：`GET /ad/api/creation/v1/aweme/get-aweme-list`
- **说明**：可选抖音号列表（awemeSourceMode=roi2）。用 云捷.千川.全域推广.抖音号列表()。来源：巨量千川

#### 创建计划

- **请求**：`POST /ad/api/creation/v1/ad/create`
- **说明**：创建计划（**全域推广与乘方共用同一个口**；URL 带 aavid + gfversion）。全域推广：externalAction=96；乘方：marGoal=1、adlabScene=1、deepExternalAction 固定 576（净成交）、smartBidType 控成本=0、overallROICostItems 一般 [3,4]（含达人佣金出价/达人自动投时 [2,3,4]）、budget = 元 × 100000 的**字符串**、一条计划可放多个商品（promotionObjectCmd.productIDs + createMultiProductsCreative）。限流返回 Too Many Requests。用 云捷.千川.全域推广.创建() / 云捷.千川.乘方.创建()。来源：巨量千川

#### 计划列表

- **请求**：`POST /ad/api/pmc/v1/uni-promotion/ad/list-required`
- **说明**：计划列表。⚠️ **全域推广与乘方是同路径、不同数据集与版本，别混用**：全域推广 dataSetKey=product_roi2_promotion（gfversion=1.0.0.4264，体是 page/page_size 那套）；乘方 SophonxDataSetKey=overall_roi_promotion_list_for_product（gfversion=1.0.0.8802，体带 _origin_ajax_/UseNewChain + Params{AdFilter, OrderBy, PageParams, Metrics, ListAdsModules, Dimensions}）。用 云捷.千川.全域推广.计划列表() / 云捷.千川.乘方.计划列表()。来源：巨量千川

#### 计划汇总

- **请求**：`POST /ad/api/pmc/v1/uni-promotion/ad/list-summary`
- **说明**：计划维度的汇总（乘方口径用它先取 data.totalNum 再逐页拉列表；gfversion=1.0.0.8802、条件挂顶层没有 Params 包装）。用 云捷.千川.全域推广.计划汇总() / 云捷.千川.乘方.计划汇总()。来源：巨量千川

#### 批量改预算

- **请求**：`POST /ad/api/data/v1/creation/batch_update_budget`
- **说明**：批量改计划预算（带 aavid + gfversion=1.0.0.1588）。体 {aavid, AdsData, UpdateBudgetInfos（两份必须一模一样）, ForceAsync:false}；金额 = 预算 × 100000，校验：**修改幅度不能小于 100 元** / >999999999.99 元 / <300 元 会报错。逐条结果 `data.results[]` 看 `flag`。全域推广与乘方同一口径。用 云捷.千川.全域推广.批量改预算() / 云捷.千川.乘方.批量改预算()。来源：巨量千川

#### 批量改投放时间

- **请求**：`POST /ad/api/pmc/v1/batch_update_schedule_type`
- **说明**：批量改计划投放时间（**只有全域推广有**；带 aavid + gfversion=1.0.0.1588）。体 {aavid, adsData:[{adId, schedule}], forceAsync:false}。逐条结果字段是 `[{objId, error}]`（**没有 error 即成功**）。用 云捷.千川.全域推广.批量改投放时间()。来源：巨量千川

#### 批量改ROI / 升级为乘方

- **请求**：`POST /ad/api/pmc/v1/uni-promotion/ad/update_uni_promotion_roi`
- **说明**：⚠️ **同路径三个版本号**：① 全域推广批量改ROI 用 `gfversion=1.0.0.1588`（体 {aavid, UpdateRoi2Infos:[{ID,value,deepExternalAction}], OptType:25, ForceAsync:false}）；② **乘方改综合ROI 同版本 1.0.0.1588，但 `OptType=28`、deepExternalAction 固定 576**；③ 升级为乘方 用 `gfversion=1.0.0.8923`（体 {UpdateRoi2Infos:[{ID,value,AdlabScene:1,DeepExternalAction,OverallROICostItems:[3,4]}], OptType:27}，体里**不带** aavid/ForceAsync、aavid 只放 URL）。逐条结果：`object.objectId` + `flag`。用 云捷.千川.全域推广.批量改ROI() / 升级为乘方() / 云捷.千川.乘方.批量改ROI()。来源：巨量千川

#### 批量操作(开启/暂停/删除)

- **请求**：`POST /ad/api/pmc/v1/batch_update_operation`
- **说明**：批量操作计划（带 aavid + gfversion=1.0.0.1588）：体 {aavid, isBatch:true, objects:[{type:1, objectID}], optType}，**optType 1=开启 / 2=暂停 / 3=删除**。逐条结果看 `data.results[].flag`。用 云捷.千川.全域推广.批量操作() / 云捷.千川.乘方.批量操作()。来源：巨量千川

#### 数据看板

- **请求**：`POST /ad/api/data/v1/common/statQuery`
- **说明**：数据看板。⚠️ 两家口径不同：全域推广 gfversion=1.0.0.4264、reqFrom=uniDataOverview、数据集 product_roi2_promotion（整体支付口径 8 项）；**乘方** gfversion=1.0.0.8851、reqFrom=uniDataOverview_trend_today、数据集 overall_roi_promotion_post_overview_for_product、Dimensions=['stat_time_hour']、8 项乘方指标（综合成本/综合ROI/综合订单成本/净成交金额/整体消耗/净成交订单数/用户实际支付净成交金额/1小时内退款率）。返回 StatsData.Totals[指标名] = {ValueStr, Comparison:{RatioStr, Ratio}}。用 云捷.千川.全域推广.数据看板() / 云捷.千川.乘方.数据看板()。来源：巨量千川

### 千川-乘方

#### 商品可投校验

- **请求**：`GET /ad/api/creation/v1/product/check-product-delivery-type`
- **说明**：创建乘方计划前筛掉不能投的商品（查询 productIds 逗号分隔、checkAll=true、aavid、gfversion=1.0.0.3979）。返回 data.results{商品ID:[原因码]}（**空数组=可投**；24=该商品正在使用商品全域推广）、data.desc{商品ID:平台原文}。用 云捷.千川.乘方.商品可投校验()。来源：巨量千川

#### 抖音号可用性校验

- **请求**：`POST /ad/api/creation/v1/aweme/check-aweme-uni-prom-enable`
- **说明**：绑了抖音号时，创建前逐商品判断这个号能不能投（URL 带 aavid + gfversion=1.0.0.3979）。体 {list:[{productId, awemeUserIds:[抖音号 userId]}]}；返回 data.checkAwemeUniPromResultMap{商品ID:{enableAwemeUserIds, disableAwemeUserIds}}。用 云捷.千川.乘方.抖音号可用性校验()。来源：巨量千川

#### 抖音号列表(v2)

- **请求**：`GET /ad/api/creation/v1/aweme/get-aweme-list-v2`
- **说明**：乘方创建页的抖音号下拉（查询 aavid、searchKeyWords、page、pageSize=100、marGoal=1、needCanApply=0、entry=1、action=1、gfversion=1.0.0.3813）。返回 data.bindAwemeUserInfos[]：userId / awemeUserInfo.name / authTypes[]（1官方 2自运营 3合作达人 4达人-单视频 5达人-直播）/ hasShopPermission / productUniPromApplyInfo / productUniPromInfo。用 云捷.千川.乘方.抖音号列表()。来源：巨量千川

#### 达人黑名单/已过滤达人

- **请求**：`GET /ad/api/creation/agw/aweme/getUniPromExcludableAwemeUids`
- **说明**：按抖音号ID反查这个号（乘方「达人黑名单 / 手动排除」用；查询 SearchObjectIDs、AdID（可空）、aavid、gfversion=1.0.0.4884）。返回 data.AwemeUserInfos[]（取第 1 条；查不到=这个号不可用），每项 {ID(UID), Name, ShowId, ShortId, SmallAvatar}。用 云捷.千川.乘方.达人黑名单()。来源：巨量千川


## 四、用 AI 开发插件（推荐：Trae）

**现在只需要下载一个「开发包」**（客户端「开发者 → 开发文档 → 下载开发包」，接口 `GET /api/docs/kit.zip`），
它已经把 SDK、UI 资源、组件库、六个可跑模板、以及**全部分模块开发文档**都带上了。

开发文档收在 `.trae/skills/yunjie-plugin-dev/` 里（skill 形态，AI 按需读取）：

| 文件 | 内容 |
|---|---|
| `SKILL.md` | **入口**：开工 5 步、铁律、按需加载表、交付自查 |
| `参考/00-快速开始.md` | 10 分钟跑通第一个插件 |
| `参考/01-SDK速查.md` … `参考/11-平台能力与组件库.md` | 分模块参考（SDK 速查 / 营销 / 商品 / 商机 / 售后 / 订单评价 / 数据存储 / 宿主能力 / 避坑 / 接口清单 / 平台能力与组件库） |

**用法（3 步）**：

1. 下载开发包 → 解压到任意目录
2. **用 Trae 打开这个目录**（`.trae/skills/` 里的 skill 自动生效）
3. 对 Trae 说需求，例如：
   「用云捷插件开发 skill，做一个批量创建单品直降活动的插件：先取活动列表，勾选商品后填折扣和时间，再创建活动」

> 为什么这样做：整套文档有十几万字，**一次塞给 AI 塞不进去**；skill 采用"薄入口 + 按需读取"，
> AI 先读 `SKILL.md`，再只读需要的 1~2 份参考，效果更好也更省 token。
> 接口清单（`参考/10-接口清单.md`）是服务端**实时生成**的，所以每次下载到的文档都对应最新接口。

## 五、提交流程（零命令行）

1. 开发者页 →「我的应用」→ 创建应用（选免费 / 收费 / **应用内收费**）
2. 收费（平台订阅）应用 →「配置定价」：**SKU 完全自定义**（多少天 / 多少钱，可加多档，单价一律按天）；
   还可以设置**免费试用天数**（0=不提供），用户每个店铺只能试用一次
   - **应用内收费**：平台不参与定价、不分账 —— 你在自己的应用里自行收款（怎么收、收多少都由你定），
     用户在应用市场里**免费安装**即可使用；这种类型没有「配置定价」入口，也不产生平台订单
3. 「我的应用 → 该应用的「版本」按钮」→ 点「**打包提交审核**」：客户端把**打包来源**打成 zip 并提交
   （源码目录首次选一次即可，之后会记住；上传时显示**进度 / 已传大小 / 预估剩余时间**；
   同一应用同时只允许一个版本在审核，要改先「撤销审核」）
4. 平台人工审核 → 通过后**生成加密发行版** → 上架应用市场（客户端下载运行的是加密发行版）
5. 收费（平台订阅）应用按用户购买的 SKU 天数计费（试用不扣费），平台按分成比例结算；
   免费与应用内收费应用不产生平台订单

**打包来源（推荐用「发布」目录；向后兼容，老插件不受影响）**：

- 源码目录下有 `发布/`（且里面有入口）→ **只打包 `发布/`**，只有它里面的内容会上传服务器
- 没有 `发布/` → 按**老规矩打包整个源码目录**（以前开发的插件照旧能传，不会报错）

```
我的插件/                ← 客户端里选这个当「源码目录」（选**上层这一层**，不是 发布/ 本身）
├── 发布/                ← 【会上传】要上线运行的文件都放这里
│   ├── index.html          入口（也可以叫 main.html / index.js / main.js）
│   ├── app.js              你的逻辑
│   ├── 云捷SDK.js          从开发包复制（别手写）
│   └── 资源/               从开发包复制（vue.min.js + element-ui/，别走 CDN）
├── 笔记.md              ← 【不上传】随便放
└── 设计稿.psd           ← 【不上传】
```

- 「本地调试」跑的也是 `发布/` 里的代码 → **调试的 = 上传的**
- 用了 `发布/` 目录时，「更新开发包（整包）」会把 `云捷SDK.js` 与 `资源/` **顺带同步进 `发布/`**

**安装/下载提示**：用户安装或打开应用时会**下载整包**，客户端会显示**进度条（进度 / 大小 / 预估剩余时间）**，
包大也不会看起来像卡死。

**安全约定（防拷贝）**：你提交的源码包**仅平台可见、永不下发给客户端**；
审核通过时平台会把源码包**加密**成发行版（应用包 `.yj`），客户端下载后在**内存里解密运行**，
磁盘上不出现明文代码、也不会留"解压目录"给人拷走。
（说明：这能挡住"拿到包/打开目录就直接抄"的人，属于**防拷贝**，不等同于强密码学保护；
真正的代码混淆仍在待做清单里。）

**插件注意事项（因为代码在内存里跑）**：
- 页面资源一律用**相对路径**（`./app.js`、`图片/a.png`）引用，**不要写绝对路径 / `file://`**
- 不要用 `location.protocol === 'file:'` 这类判断（插件页面的协议是 `yunjieapp:`）
- `localStorage` / `IndexedDB` 正常用即可（按「应用 + 店铺」各存一份，跨次保留）
- 「本地调试」仍然是加载你本机目录（明文源码），不受影响

**收益与提现**：
- 收益 = 你的应用产生的**平台订阅收入** × 分成比例（试用订单金额为 0，不影响；退款订单不计入）
  - 注意：**应用内收费**的钱是你在应用内自己收的，不经过平台、平台也不抽成，因此**不计入**这里的收益
- **结算时机：订单「到期后 15 天」才结算入账**（不是下单就入账）——已结算的才进「开发者余额」（可提现）
- 你在「收益结算」页的**订单结算明细**里能看到每一笔订单的状态：
  `待结算`（还没到可结算时间）/ `已结算`（已进余额）/ `已退款`（被退款作废，不计收益）
- 提现额度 = 开发者余额（申请提现时**预先扣除**；客服驳回会**原路返还**；客服打款完成则保持扣除）
- 提现流程：先在「收益结算」页填**收款信息**（支付宝账号 + 收款二维码）→ 点「申请提现」填金额 →
  平台客服按收款码转账 → 转账完成后这笔申请变为「已完成」

**用户退款 / 平台强制退款（影响你的收益）**：
- 用户在客户端下单后 **3 天内**可以自助退款（免费试用订单不能退）；平台也可以在后台**强制退款**（会写明原因）
- 同一个用户对同一个应用**只允许退一次**；退过之后他再次订阅，客户端不再显示退款按钮
- 退款后：用户余额原路退回，该订单变为「已退款」并**不计入你的收益**；
  若这笔订单**已经结算给你**，你的开发者余额会按该单分成金额**扣回**（可能变负，表示欠平台）

## 六、常见问题

- **10008 / 10001010A**：通常与签名或来源参数有关。本项目由页面自身发请求，正常不会出现；
  若出现，先到「接口调试」页对同一接口复现，确认服务端下发的参数。
- **令牌（__token）**：写接口（如创建活动）需要。绑定店铺时客户端会自动采集并上报，
  SDK 用 `取店铺令牌(店铺ID)` 获取。
- **店铺掉登录**：接口会返回登录态错误，需要在店铺标签里重新登录抖店（平台可能 48 小时掉线）。
- **店铺标签没打开**：不用管，SDK 会自动打开并等待页面就绪（首次会慢几秒）。

---

## 七、插件开发避坑清单（实战经验，强烈建议先读）

> 下面每一条都是**实际踩过**的坑，照着做能省很多时间；最后一节是最有效的排查顺序。

### 7.1 Vue2 模板里，中文方法名必须带括号
- ❌ `@click="获取商品"` → 被编译成 `function($event){获取商品}`（只读函数引用、**不调用**）
  → 点了**毫无反应，而且控制台不报错**（最难查的一类问题）
- ✅ `@click="获取商品()"`；需要事件参数就显式传：`@selection-change="选中变化($event)"`、`@change="切换全选($event)"`
- 根因：Vue2 编译器只把 **ASCII 标识符**当成"方法路径"，中文方法名被当成内联表达式
- 反推特征：`@click="弹窗 = true"`（赋值）**有效**、ElementUI 自己的页签能切、`mounted()` 里调的方法有效 → 就是这个坑

### 7.2 模板里引用的名字，必须在 data / computed 里真实存在
- ❌ data 里叫 `选择移除商品`，模板写成 `已选移除商品` → 渲染直接抛
  `ReferenceError: 已选移除商品 is not defined`（指向 vue.min.js 的渲染函数），严重时整页不渲染
- 改名要同步 **3 处**：`data` 定义、所有模板引用、`methods` 里的读写

### 7.3 ⚠️ 属性名里带 ASCII 大写字母会传不进组件（很隐蔽）
- HTML 解析器会把**属性名里的 ASCII 大写字母小写化**：
  写 `<sku-search :店铺ID="当前店铺ID">`，到组件时属性名已变成 `:店铺id`，
  跟 props 里的 `店铺ID` 对不上 → **prop 收不到值**（症状：明明选了店铺，组件还提示"请先选择店铺"）
- ✅ 统一用 **kebab-case 全小写**：`<sku-search :shop-id="当前店铺ID">`
- 规律：**属性名里别出现 ASCII 大写**；中文部分不受影响，所以纯中文属性名（如 `:店铺="…"`）是安全的

### 7.4 判断接口成败，不能看 data 有没有值
- 抖店写接口成功时经常返回 `{"code":0,"data":null}`（例：`setFlashStatus` 作废活动）
- ❌ 用 `取数据(响应) !== null` 判断 → 会把**成功误判成失败**（日志里出现 "失败 —— code=0" 这种自相矛盾的提示）
- ✅ 单独写一个 `响应成功(响应)`（`code===0` 或 `成功!==false`）；`取数据()` 只负责取数据

### 7.5 ElementUI 按钮 loading == disabled
- `el-button` 内部是 `:disabled="buttonDisabled || loading"`：某次调用卡住不返回，
  loading 永远为 true → **按钮永久点不动、且什么都不提示**
- 对策：入口按钮别绑 loading（重活放弹窗里做）；**所有桥调用必须加超时**（见 7.6）

### 7.6 所有桥调用都要加超时
```js
function 限时(承诺, 毫秒, 提示) {
  return Promise.race([承诺, new Promise(function (_, 拒绝) {
    setTimeout(function () { 拒绝(new Error(提示 || '请求超时')) }, 毫秒)
  })])
}
```

### 7.7 依赖放插件本地，不要走 CDN
- CDN 首屏要联网拉约 1MB，且"多 CDN 兜底链"在第一个不通时要**等超时**才试下一个 → 表现就是"加载很慢"
- ✅ 把 Vue / ElementUI 放插件目录的 `资源/` 下，用相对路径静态引用（离线也能用，秒开）

### 7.8 时间处理：`String(new Date())` 不能直接塞给 `new Date()`
- `String(new Date())` 是 `"Mon Sep 11 2026 ..."` 这种带星期的格式，
  按"把日期与时间之间的空格换成 T"的思路处理会得到 `"MonTSep ..."` → 非法 → 解析失败返回 undefined
- ✅ 显式判断：`值 instanceof Date` / 数字要区分秒与毫秒（`>1e12` 视为毫秒）

### 7.9 抖店报错有时**不是 JSON**
- 形如：`code=520404039 message=RPC 调用失败-... prompts=活动配置获取失败{...}`（纯文本，`JSON.parse` 会失败）
- ❌ 一律报"响应不是 JSON（可能登录已失效）" → 会把业务错误误报成登录问题，排错方向全错
- ✅ 先 `/code=(-?\d+)/` 与 `/message=(...)/` 把 code/message 抽出来当业务错误显示

### 7.10 要"每行一个"的输入框必须用 textarea
- 单行 `el-input`（没有 `type="textarea"`）**打不出换行**，回车不生效 → 占位文案写"每行一个"就是假的
- ✅ `type="textarea"`；拆分时用 `/[\s,，;；]+/` 一次兼容换行 / 逗号 / 空格

### 7.11 不要再给插件套一层"假窗体"
插件本身就运行在客户端窗口里，再做标题栏 / 最小化 / 最大化 / 拖拽都是多余的。

### 7.12 单个活动有硬上限：**200 个商品 / 2000 个 SKU**（超过必须自己分片）

- 超过会直接报错：`单个活动最多支持200个商品，已达到数量限制`
- **必须自己分片**：把商品按"每片 ≤200 商品 且 ≤2000 SKU"贪心装箱，逐片各创建一个活动
  （活动名可以重复用；分片结果建议用 `名称 #1 / #2 …` 在界面上区分展示）
- 分片前要知道每个商品的 SKU 数：用 `batch_query_sku_list_v2` 查，`sku_list.length` 即该商品的 SKU 数
- ⚠️ **多个抖店接口单次最多 100 个商品**（`batch_query_sku_list_v2`、`query_available_product_v2` 等）
  → 商品多时这些调用也要按 100 个一批，否则会查不到 / 报错
- 分片之间留间隔（建议 2 秒），降低风控

### 7.13 限时抢购创建活动（`createFlashAndGoods`）的关键字段语义

- `shop_stype`（优惠类型）：**1=一口价 / 2=直降 / 3=打折**
- `shop_svalue`（优惠值，单位分）：含义随 `shop_stype` 变
  - 直降 → **直减金额**（分）：活动价 = 原价 − 直减金额
  - 一口价 → **活动价**（分）
  - 打折 → **折扣数值**（1-99，85 = 8.5 折）：由平台按 原价 × 折扣 算活动价
    （只能填一个值，所以必须是"折扣"而不是折后价——折后价会因 SKU 而异）
- `limit_stock_type`：**1=不限库存**，此时每个 SKU 的 `camp_stock_num` 必须是 `'0'`，
  填非 0 会被平台拒绝（`普通秒杀不限库存，不需要库存信息`）；限制库存时才用 `camp_stock_num` 控制活动库存
- ⚠️ **只有"限量抢购"（`LimitQuantity`）才需要库存设置**：`LimitTime` 限时抢购**只限制时间、不管库存**
  （`limit_stock_type='1'` + `camp_stock_num='0'`）→ 做界面时，限时抢购下**不要给用户显示库存选项**
- `pre_begin_time`：预热开始时间；不预热时**等于 `begin_time`**；
  开启预热 = `begin_time − 预热天数 − 预热小时`（预热时间与开始时间重合时需往前挪，否则校验不过）
- `order_expire_time`：订单取消时间，**单位秒**（前端常见选项 5/10/15/30/60 分钟 → 300/600/900/1800/3600）
- `sold_out_type`：售罄后策略，**0=恢复原价继续售卖 / 1=停止售卖**
- `business_code`：活动类型（`LimitTime` 限时抢购 / `LimitQuantity` 限量抢购 / `OrdinaryTimeBuy` 普通降价促销）

### 7.14 排查顺序（照走最快）
1. 控制台过滤插件自己的日志前缀，**先确认跑的是不是最新代码**（建议插件自带 `build-N` 标记）；
   不是 → **关掉插件标签重新打开**（已打开的标签不会自动换代码）
2. 看红色 error 的完整原文
3. 看"请求 / 响应"那一对，核对接口路径、参数、响应码、响应体
4. 页面顶部有错误条 → 脚本顶层报错，按文字定位
5. 按钮点了没反应 → 先查 7.1（中文方法名没带括号）

### 7.15 ⚠️ 别拿 `window.云捷`（桥）去"自检" SDK 能力 —— 会误报"缺少能力"

`window.云捷` 是客户端注入的**桥**，只提供底层能力：
请求 / 调用抖店接口 / 店铺列表 / 打开店铺 / 浏览器 / 文件 / 系统 / 缓存 / 数据库 / AI / 定时。

而 `营销` / `商品` / `售后` / `订单` / `评价` 这些**业务封装全在 SDK（`云捷SDK.js`）里**，
桥上根本没有 —— 所以下面这种自检必然"全缺"（典型误报：
`缺少能力：售后.策略列表、售后.策略详情、售后.更新策略、售后.退货地址列表…`）：

```js
// ❌ 错：查的是桥，售后.* 在桥上永远不存在
const 路径表 = ['售后.策略列表', '售后.退货地址列表']
const 缺 = 路径表.filter((路径) => !取路径(window.云捷, 路径))
```

✅ 正确做法：

- 要查能力就查**你 import 进来的那个 SDK**：`import 云捷 from './云捷SDK.js'` → 查 `云捷.售后.策略列表`
- 或者**干脆不做这种自检**：SDK 里没有的方法，调用时会直接抛错，错误信息足够定位；
  自检写错了反而会拦住本来能用的功能
- 想判断"开发包是不是旧的"看 `云捷.开发包版本`；太旧就到客户端
  「开发者中心 → 我的应用 → 版本 → 开发包版本」一键更新（见 3.4 节）

### 7.16 想让插件"记住上一次填的表单"：用 `云捷.文件` 长期存 + 防抖自动保存

长表单（几十个字段）用户不想每次重填，标准做法是**自动记忆 + 下次打开带出**：

| 存储 | 生命周期 | 用法 |
|---|---|---|
| `云捷.文件.写入('配置/创建配置.json', 文本)` | **长期**（清缓存不删，要主动删） | **首选** |
| `云捷.缓存.写('创建配置', 文本)` | 清缓存即丢，可重建 | 兜底（写文件失败 / 旧内核） |

```js
// 存：表单任何变化 → 防抖（800ms 这种量级）再写，别每敲一个字符写一次盘
watch: { 表单: { deep: true, handler() { 防抖(保存配置) } } }

// 读：先文件、再缓存（顺序与写相反）
const { 内容 } = await 云捷.文件.读取('配置/创建配置.json')   // 不存在 → { 成功:false }，**不抛错**
```

四个必须注意的点：

1. **恢复/重置动作自己要"静音"**：先置 `this._配置静默 = true`，改完数据在 `$nextTick` 里复位，
   否则"恢复"这个动作又会触发一次保存（Vue watcher 在本轮 flush 中执行，早于 `$nextTick` 回调，标志位拦得住）
2. **别整体替换嵌套对象**：用 `Object.assign(旧值, 新值)` 逐项覆盖，
   这样插件升版新增的字段仍保留默认值
3. **有时间性质的字段单独存**（如活动开始/结束时间 + 保存时间），恢复时只有"还没过期"才带出，
   别让用户带着过期时间去提交
4. 默认值要在 `mounted` 里先备份（`this._默认创建 = 深拷贝(表单)`），"恢复默认配置"才有基准；
   所有文件/缓存调用同样加超时（见 7.3），存不上**不能影响主流程**

### 7.17 ⚠️ 单品直降/限时抢购的平台强制门槛：优惠 ≥ 1 元、打折不得高于 9.5 折

创建活动时**每个 SKU 的优惠力度都要过平台门槛，否则整个活动报不上名**：

| 优惠方式 | 门槛 |
|---|---|
| 全部（一口价/直降/打折） | **优惠金额 ≥ 1 元**（活动价 ≤ 原价 − 100 分）|
| 打折 | **折扣不得高于 9.5 折**（折扣数值 ≤ 95，即优惠力度 ≥ 5%）|

两头都要满足时**取更严格的**：允许的最高活动价 = `min(原价 − 100, floor(原价 × 95 / 100))`（打折时）。

- `shop_svalue` 的含义随 `shop_stype` 变：`'1'` 一口价 = 活动价（分）；`'2'` 直降 = 直减金额（分）；
  `'3'` 打折 = **折扣数值（1-95）**。所以打折模式的"补差"要**反推折扣**：
  折扣 = `floor(上限价 × 100 / 原价)`（向下取整，向上取整会越过门槛）
- 常见的两种处理（插件里做成「自动跳过 / 自动补差」两个开关）：
  - 跳过：不满足门槛的 SKU 不加入活动
  - 补差：把优惠值调到刚好满足门槛（9.9 折 → 9.5 折、直减 0.5 元 → 1 元、一口价 19.5 元 → 19 元）
- 原价 ≤ 1 元的 SKU **怎么算都满足不了**（活动价最低 1 分）→ 只能丢弃，别硬提交
- 别把"活动价兜底 1 元"当成这个门槛：那是价格下限，与"优惠力度 ≥ 1 元"是两回事
- 页面体验：**给用户按"折"显示与填写**（8.5 折 / 9.5 折），提交前再 `×10` 还原成折扣数值（85/95）——
  中间值（`shop_svalue`）始终是数值，别把"折"直接提交上去

---

## 八、可复用组件（直接下载，放进插件即可用）

> 全部组件都在**开发包**（`GET /api/docs/kit.zip`）的 `组件/` 目录里，解压即可用，无需单独下载。

| 组件 | 下载地址 | 标签 | 作用 |
|---|---|---|---|
| **商品输入 / 选择**（sku-search） | `GET /api/docs/components/sku-search.js` | `<sku-search>` | **六种加载方式合在一个组件里**（组件内切换）：① **加载全部** ② **售卖中** ③ **已下架**（这三个都是按商品列表从第 1 页翻到最后一页，显示进度与**预估剩余时间**）④ **导入商品ID**（粘贴即读，可自动补全名称/价格/库存）⑤ **自定义筛选**（状态 + 商品售价 + 商品销量 + 创建/上架/下架时间 + 运费模板）⑥ **SKU编码**（逐个翻页搜索）→ 列表可排序/勾选 → 抛出选中的商品ID数组 |

> ⚠️ **"商品输入"一律用这个组件**（插件里不要再自己写商品ID输入框 / 搜索框 / 加载商品下拉）—— 不管什么场景，
> 最终都只是要**商品ID**：加载全部/售卖中/已下架、直接贴商品ID、自定义筛选、搜 SKU编码，都能拿到商品ID。
> 平台上限：**最多 10000 条商品**（每页 100 → 最多 100 页），到 1 万条就停并提示"店铺共 N 条、只取到前 10000 条"。

**用法（3 步）**

1. 下载 `sku-search.js`，放进插件目录（如 `组件/SKU搜索.js`）
2. 入口 HTML 里**静态引入**（必须在 `vue.min.js` 之后、业务脚本之前）：
   ```html
   <script src="./组件/SKU搜索.js"></script>
   ```
3. 模板里直接用（注意 **`:shop-id` 全小写**，原因见 7.3）：
   ```html
   <sku-search :shop-id="当前店铺ID" :business-code="活动业务码"
     :start-time="活动开始时间" :end-time="活动结束时间"
     :enable-join-check="true"
     @change="SKU搜索变化($event)"></sku-search>
   ```
   （`:enable-join-check="true"` 只有**单品直降**这类要报名活动的插件才传；不传 = 不显示"检测是否已参加活动"）

**props**：`shop-id`（店铺ID，不传则组件会问客户端要默认店铺）、`提示`（SKU编码 方式的占位文案）、
`默认方式`（打开时停在哪种加载方式：`all`/`selling`/`offLine`/`product_id`/`custom`/`sku_code`，**默认 `product_id`**；
  例 `<sku-search 默认方式="all" …>`）、`每页`（默认 100）、
`最多页数`（"搜索宝贝"每个编码最多翻几页，默认 10）、`全部最多页数`（加载类方式最多翻几页，**默认 0 = 一直翻到最后一页**，
但**始终受平台 10000 条上限约束** → 每页 100 时最多 100 页）、
`间隔毫秒`（默认 2000，同店铺该接口限流间隔）、`请求器`（可选，不传则组件自己调 `云捷.调用抖店接口`）、
`business-code` / `start-time` / `end-time`（只有要检测"是否已参加活动"时才需要）、
`enable-join-check`（Boolean，**默认 false**：是否显示「检测是否已参加活动」勾选）

**事件**：`change` = **勾选中的商品ID数组**（**一行都没勾选就是空数组** —— 选哪几个才交给宿主哪几个，
  宿主不勾选时应提示用户去勾选、别硬提交）；
`完成` = 结果明细数组
（`{ row_key, sku_code, product_id, product_name, img, price, price_higher, stock_num, sell_num, 已参加, status }`，
  列表类加载方式还会带 `tab`（商品状态）/ `draft_time`（创建时间）/ `discount_price` 等列表接口字段，
  列表里也会**自动多出一列「商品状态」**）

> ⚠️ **绑事件时中文方法名必须带括号**：`@change="SKU搜索变化"` 会被 Vue2 编译成 `function($event){SKU搜索变化}`
>   （只读引用、**不调用**）→ 表现就是"明明勾选了，宿主却收到 0 条 / 说没商品"。正确写法：
>   `@change="SKU搜索变化($event)"`、`@完成="SKU搜索完成($event)"`（详见 7.1）。

> 💡 **宿主想做自己的表**：组件本身就是"加载商品 + 结果列表 + 勾选"的工具，宿主只要在 `change` / `完成`
>   里拿数据即可 —— 常见做法是：组件常驻在页面里负责选商品，宿主再拿勾选的商品ID 自己做业务
>   （检测 / 改价 / 报名…），并把业务结果渲染成宿主自己的结果表（组件里也有自己的一张列表）。

**列表能力（用户侧）**

- 列：商品名称 / 库存 / **销量（可排序）** / 最低价 / 最高价 / 状态（`可报名` / `已参加活动` / `未找到`）
- 排序：点表头排序（销量 / 库存 / 最低价 / 最高价）—— 排的是**全部数据**，不只是当前页
- **大列表不卡（1 万条也能用）**：数据全量在内存，表格**只渲染当前页**（每页 20/50/100/200 可选，翻页保留勾选）；
  取商品ID / 去重 / 勾选统计都用**对象当集合**（O(n)），不用 `indexOf`（那是 O(n²)，1 万条会明显卡）；
  读取过程中**视图节流**（每 5 页/每 5 个编码才刷一次列表，结束再统一刷一次），避免上百次 re-render
- 体验细节：商品小图**鼠标悬停即放大预览**（预览层 fixed 定位，不会被表格单元格裁掉）；
  **点商品ID 直接复制**（整批复制用「复制选中ID」）；图片 `loading="lazy"`，列表宽度跟随宿主容器
- 勾选：**「全选全部 N 条」**（跨页全选）、反选、**勾选有销量**、**勾选无销量**、删除选中、复制选中ID
  （全选/反选作用于**全部数据**；el-table 表头那个勾选框只勾当前页，点它时会提示"要跨页全选请点「全选全部」"）
- 快捷键：**单击行＝勾选/取消该行**（可连续点着加选，不会清掉其它已选）；**Shift+单击＝范围内整段勾选/取消**；
  **按住鼠标在列表里拖矩形框＝框选**（框到的行**实时**勾上、累加不清空别的；框只画在表格数据区内，
  拖到表格上/下边缘时**列表自动跟着滚**，能继续往上或往下选）；**Ctrl+A＝全选**（焦点在列表上时）
- 「SKU编码」模式的去重口径（别搞混）：① 输入的**编码先去重**（同一编码只搜一次）；
  ② **跨编码**按商品ID去重（同一商品被多个编码命中时只留一条）；③ **编码内部不去重**——
  一个编码匹配多少条就保留多少条（同一商品的多个 SKU 也是多条），翻页只看接口返回的 total
- 加载类方式（加载全部 / 售卖中 / 已下架 / 自定义筛选）：开始前**先弹确认**（提示"每页 2 秒、商品多时可能很久"），
  翻页过程中按**商品ID去重**（分页边界会重复返回同一商品）
- 自定义筛选：条件与抖店商品管理的筛选一致（状态 / 商品售价 / 商品销量 / 创建时间 / 上架时间 / 下架时间 / 运费模板）；
  价格填「元」（组件内部转「分」），上架时间只在「售卖中」用、下架时间只在「已下架」用；条件可留空
- 已参加检测（**只有传了 `enable-join-check` 才出现，也只有"单品直降"这类要报名活动的插件才需要**）：
  **必须先有活动开始/结束时间**，否则不能检测；传了就**默认勾上 → 读取时边读边检测**
  （读到的商品每凑够 100 个就提交一批 `POST /marketing/activity/v1/query_available_product_v2`，
  `activityToolType: 26` + `business_code` + `start_time/end_time` + `product_str_list`）——
  ⚠️ 清单**就在 `data` 里、直接是数组**：`{ code: 0, data: [{ product_id, allow, reject_msg, … }] }`，
  **`allow: true` 才是可报名**；`allow: false` 的行带 `reject_msg`（例："已参与同时段限时购买活动"）；
  **不能报名的直接从列表里过滤掉**（连勾选一起清掉），勾选框旁提示过滤了几条，
  并可点「查看过滤掉的商品 N」看平台原因 / 导出商品信息 CSV / 复制全部商品ID；
  某一批接口没返回清单时那一批不做判断，避免误杀

> 组件内自带样式（自动注入 `<style>`），宿主不需要额外配 CSS。
> 组件源码维护在服务端 `组件库/` 目录，下载到的就是最新版。

## 九、示例插件（直接下载，最快上手）

> 这些都是**能跑通的完整插件**，当模板/参考最快：
> 下载 zip → 解压到本机任意目录 → 客户端「开发者中心 → 我的应用 → 版本 → 选择/更换目录」选中该目录 → 点「**本地调试**」立刻就能跑。
>
> 部分示例里带了《开发经验与接口速查》《云捷开发者文档》等 md，是实战踩坑笔记，写新插件前值得先扫一遍。
> 这些 zip 由平台管理员上传维护（后台「示例插件」页），列表与下载地址都是实时的。

| 示例插件 | 说明 | 下载 |
|---|---|---|
| **异常包裹** | — | `GET /api/examples/download/18` |
| **售后赔付导出** | — | `GET /api/examples/download/17` |
| **店管家批量设置结算价简称** | — | `GET /api/examples/download/16` |
| **店管家批量绑定厂家** | — | `GET /api/examples/download/15` |
| **优惠券** | — | `GET /api/examples/download/14` |
| **新人券** | — | `GET /api/examples/download/13` |
| **涉税信息** | — | `GET /api/examples/download/12` |
| **飞鸽催评价** | — | `GET /api/examples/download/11` |
| **多件满减** | — | `GET /api/examples/download/10` |
| **店铺数据列表** | — | `GET /api/examples/download/9` |
| **店铺首页信息** | — | `GET /api/examples/download/8` |
| **单品直降活动** | — | `GET /api/examples/download/7` |
| **采集商品素材** | — | `GET /api/examples/download/6` |


下载页（浏览器点着下载）：`GET /api/docs/examples`
