API及SKILL
产品数据 API 接口文档与 Qoder CLI Skill 管理
接口目录
基本信息
http://localhost:5000/apiapplication/json产品管理接口
/api/products
获取所有产品
返回所有主产品列表,包含关联的样品状态信息。支持 ?pallet_id=X 按货盘过滤。服装类产品 (fu_zhuang) 自动嵌入 variants[] 数组。
[
{
"id": "prod_1",
"name": "蔚蓝男士淡香水",
"sku": "LF-zi",
"sku_wn": "2026_P1",
"product_no": "#P1",
"product_type": "xiang_shui",
"price": "35",
"sample_status": "existing"
},
{
"id": "prod_570",
"name": "FOG卫衣",
"sku": "FOG01",
"product_type": "fu_zhuang",
"variants": [
{"id": "prod_571", "variant_size": "S", "variant_supplier": "供货商A", "price": "120", "sku": "FOG01-S-A"},
{"id": "prod_572", "variant_size": "L", "variant_supplier": "供货商B", "price": "135", "sku": "FOG01-L-B"}
]
}
]
/api/products
新增产品
创建一个新产品,系统自动生成 id、product_no、sku_wn。服装类产品 (fu_zhuang) 可通过 variants 数组同时创建变体。
{
"name": "蔚蓝男士淡香水", // 必填 - 产品名称
"sku": "LF-zi", // 必填 - 原始SKU
"pallet_id": 1, // 选填 - 所属货盘ID(默认1)
"prefix": "P", // 选填 - 编号前缀(默认P, 服装用F)
"category": "男士香水", // 选填 - 分类
"product_type": "xiang_shui", // 选填 - 产品类型(name_en)
"price": "35", // 选填 - 价格
"stock": "10", // 选填 - 库存
"spec": "100ml", // 选填 - 规格
"description": "木质调", // 选填 - 描述
"warehouse": "SH-01", // 选填 - 仓库
"image_path": "/i/abc123def....jpg", // 选填 - NGS 图片路径(需先调 /api/ngs/upload 获取)
"variants": [ // 选填 - 服装变体数组
{"size": "S", "supplier": "供货商A", "price": "120", "stock": "5"},
{"size": "L", "supplier": "供货商B", "price": "135", "stock": "8"}
]
}
{
"success": true,
"id": "prod_569",
"product_no": "#P463",
"sku_wn": "2026_P463",
"variants_created": 0 // 服装产品时返回变体创建数
}
/api/products/{product_id}
修改产品
更新指定产品的字段,仅传入需要修改的字段即可。
// PUT /api/products/prod_1
{
"name": "新名称", // 可选 - 产品名称
"price": "42", // 可选 - 价格
"stock": "20", // 可选 - 库存
"category": "女士香水" // 可选 - 分类
// 可更新字段: name, sku, category, product_type,
// price, stock, spec, description, warehouse,
// image_path, product_no, sku_wn,
// parent_id, variant_size, variant_supplier
}
{"success": true}
/api/products/{product_id}
删除产品
删除指定产品(不会删除关联的样品数据)。服装主产品会级联删除所有变体子行。
{"success": true}
/api/products/{product_id}/variants
追加变体
为已存在的服装主产品追加一个变体。变体继承主产品的 product_type、category、pallet_id 等公共字段。
// POST /api/products/prod_570/variants
{
"size": "XL", // 必填 - 尺寸
"supplier": "供货商A", // 必填 - 供货商
"price": "125", // 选填 - 价格
"stock": "4" // 选填 - 库存
}
{
"success": true,
"id": "prod_573",
"sku": "FOG01-XL-A",
"sku_wn": "2026_F1-XL"
}
/api/clear_data
清空数据
清空指定数据表的所有数据。此操作不可逆!
{
"target": "products", // 可选值: products, samples, all
"pallet_id": 1 // 选填 - 指定货盘
}
{"success": true, "message": "products 数据已清除"}
/api/products/{product_id}/perfume_details
获取香水详情
获取指定产品的香水详细信息,包括品牌、系列、适用性别、前中后调、产品简介和相关链接。如果该产品从未填写过详情,返回所有字段为空字符串的默认值。
{
"product_id": "prod_0",
"brand": "Raffa",
"series": "Classic",
"gender": "男女都适用",
"note_top": "柑橘 佛手柑",
"note_middle": "茉莉 玫瑰",
"note_base": "麝香 琥珀",
"intro": "经典清新香型",
"link1_title": "官方",
"link1_url": "https://example.com",
"link2_title": "",
"link2_url": "",
"updated_at": "2026-05-02 14:40:32"
}
/api/products/{product_id}/perfume_details
更新香水详情
新建或更新指定产品的香水详情(UPSERT)。所有字段均为可选,未传入的字段将保存为空字符串。
// PUT /api/products/prod_0/perfume_details
{
"brand": "Raffa", // 可选 - 品牌名称
"series": "Classic", // 可选 - 系列或型号
"gender": "男女都适用", // 可选 - 男性/女性/男女都适用
"note_top": "柑橘 佛手柑", // 可选 - 前调
"note_middle": "茉莉 玫瑰", // 可选 - 中调
"note_base": "麝香 琥珀", // 可选 - 后调
"intro": "经典清新香型", // 可选 - 产品简介
"link1_title": "官方", // 可选 - 链接1标题
"link1_url": "https://...", // 可选 - 链接1 URL
"link2_title": "", // 可选 - 链接2标题
"link2_url": "" // 可选 - 链接2 URL
}
// 成功
{"success": true}
// 失败 - 产品不存在
{"error": "产品不存在"} // HTTP 404
货盘管理接口
/api/pallets
获取所有货盘
返回所有货盘列表,包含每个货盘下的产品数量。
[
{
"id": 1,
"name": "香水",
"description": "常规业务管理",
"created_at": "2026-04-29 16:15:59",
"product_count": 463
}
]
/api/pallets
创建货盘
创建一个新货盘。可选在创建时直接指定编号前缀配置,避免创建后再调用 /sku-config 接口。
{
"name": "新货盘名称", // 必填 - 货盘名称
"description": "货盘说明", // 选填 - 货盘描述
"product_no_prefix": "#P", // 选填 - 编号前缀, 1-12 ASCII字符, 如 '#A' / '#M' / 'P'
"sku_wn_year_prefix": "2026_" // 选填 - SKU_WN年份前缀, 0-16字符; 留空=当年
}
{"success": true, "id": 5}
/api/pallets/{pallet_id}
修改货盘
更新指定货盘的名称和描述。
// PUT /api/pallets/1
{
"name": "新名称", // 必填 - 货盘名称
"description": "新说明" // 选填 - 货盘描述
}
{"success": true}
/api/pallets/{pallet_id}
删除货盘
删除指定货盘。货盘下有产品时拒绝删除。
// 成功
{"success": true}
// 失败 - 货盘下有产品
{"error": "该货盘下还有 463 个产品,请先清空产品后再删除"}
/api/pallets/{pallet_id}/default-image
更新货盘默认图
更新货盘的默认图片(通用/男/女/中性)。只更新请求体中出现的字段,不会清空未传入的字段。图片路径需先通过 /api/ngs/upload 上传获取。
// PUT /api/pallets/1/default-image
{
"default_image": "/i/abc123....jpg", // 选填 - 通用默认图
"default_image_male": "/i/def456....jpg", // 选填 - 男性默认图
"default_image_female": "/i/ghi789....jpg", // 选填 - 女性默认图
"default_image_unisex": "/i/jkl012....jpg" // 选填 - 中性默认图
}
{"success": true}
/api/pallets/{pallet_id}/sku-config
更新SKU前缀配置
更新货盘的 product_no 和 sku_wn 前缀配置,同时批量重命名该货盘下所有产品的编号和SKU。仅允许 ASCII 可见字符。
// PUT /api/pallets/1/sku-config
{
"product_no_prefix": "#P", // 必填 - 编号前缀, 1-12字符, 如 '#P' / 'P' / '001'
"sku_wn_year_prefix": "2026_" // 选填 - SKU_WN年份前缀, 0-16字符; 留空=当年
}
{
"success": true,
"product_no_prefix": "#P",
"sku_wn_year_prefix": "2026_",
"updated_product_no": 12, // 被重命名的 product_no 数量
"updated_sku_wn": 12, // 被重命名的 sku_wn 数量
"updated_sku": 8 // 被重命名的 sku 数量
}
供应商管理接口
/api/suppliers
获取所有供应商
返回所有供应商列表,包含每个供应商的产品引用数和关联货盘信息。支持 ?pallet_id=X 过滤为对该货盘可见的供应商(未关联任何货盘的供应商全局可见)。
[
{
"id": 1,
"name": "广州香水批发",
"phone": "13800138000",
"wechat": "gz_perfume",
"note": "主营大牌香水",
"created_at": "2026-05-01 10:00:00",
"updated_at": "2026-05-01 10:00:00",
"product_count": 42, // 引用该供应商的产品数
"pallet_ids": [1, 3], // 关联的货盘ID
"pallet_names": ["香水", "服装"] // 关联的货盘名称(与pallet_ids同序)
}
]
/api/suppliers/{supplier_id}
获取单个供应商
根据 ID 获取单个供应商的详细信息。
// 成功 - 返回完整供应商对象(同列表中的单条)
{"id": 1, "name": "广州香水批发", ...}
// 失败 - 供应商不存在
{"error": "供应商不存在"} // HTTP 404
/api/suppliers
创建供应商
创建一个新供应商。name 不可重复。pallet_ids 控制供应商对哪些货盘可见;为空数组表示全局可见。
注意:导入产品时 Excel 中的「供应商」列按名称匹配,供应商必须已存在才能匹配成功。请先创建供应商再导入产品。
{
"name": "广州香水批发", // 必填 - 供应商名称(不可重复)
"phone": "13800138000", // 选填 - 电话
"wechat": "gz_perfume", // 选填 - 微信号
"note": "主营大牌香水", // 选填 - 备注
"pallet_ids": [1, 3] // 选填 - 关联货盘ID; []=全局可见
}
// 成功 - 返回创建的供应商对象
{"id": 5, "name": "广州香水批发", "phone": "...", ...}
// 失败 - 名称为空
{"error": "供应商名称不能为空"} // HTTP 400
// 失败 - 名称重复
{"error": "供应商 \"广州香水批发\" 已存在"} // HTTP 400
/api/suppliers/{supplier_id}
修改供应商
更新指定供应商的信息。pallet_ids 传入时会全量替换原有的关联关系。
// PUT /api/suppliers/1
{
"name": "广州香水批发(新)", // 必填
"phone": "13900139000", // 选填
"wechat": "gz_perfume_v2", // 选填
"note": "已升级", // 选填
"pallet_ids": [1] // 选填 - 全量替换关联
}
// 返回更新后的完整供应商对象(含 product_count, pallet_ids, pallet_names)
{"id": 1, "name": "广州香水批发(新)", "product_count": 42, ...}
/api/suppliers/{supplier_id}
删除供应商
删除指定供应商。如有产品引用该供应商,默认拒绝删除;加 ?force=1 可强制删除(产品的 supplier_id 会被置为 NULL)。
// 普通删除(有产品引用时失败)
DELETE /api/suppliers/1
// 失败:
{"error": "该供应商已被 42 个商品引用,无法直接删除", "product_count": 42}
// 强制删除(产品引用被解除)
DELETE /api/suppliers/1?force=1
// 成功:
{"success": true, "unlinked_products": 42}
导入导出接口
/api/upload_products
Excel导入产品
通过 Excel 文件批量导入产品到指定货盘。按 SKU 匹配:已有产品则更新(仅更新非空字段),不存在则新建。
注意事项:
- 供应商必须先创建:Excel 中「供应商」列按名称匹配,不存在的供应商会导致该行被跳过并报错
- 产品分类必须是字典值:「产品分类」列使用中文名(如"香水"、"服装"),必须在系统字典
chan_pin_fen_lei中已配置 - SKU 必填:每行必须有 SKU,空 SKU 的行会被跳过
- 新建需产品名称:新增产品时「产品名称」必填,否则跳过
- 图片路径格式:「图片路径」列填
/i/sha256.ext(通过/api/ngs/upload上传获取)或http(s)://URL
Content-Type: multipart/form-data
file: 产品Excel文件 (.xlsx / .xls) — 必填
pallet_id: 目标货盘ID (默认=1) — 选填
┌─────────────┬────────┬──────────────────────────────────────────────┐
│ 列名 │ 必填 │ 说明 │
├─────────────┼────────┼──────────────────────────────────────────────┤
│ SKU │ ✅ 必填 │ 每行唯一标识,用于匹配已有产品 │
│ 编号 │ 选填 │ product_no, 如不填系统自动生成 │
│ SKU_WN │ 选填 │ 内部SKU, 如不填系统自动生成 │
│ 产品名称 │ 新建必填│ 新增产品时必须填写 │
│ 产品分类 │ 选填 │ 中文分类名, 如"香水""服装", 需在字典中已配置 │
│ 价格 │ 选填 │ │
│ 库存 │ 选填 │ │
│ 规格 │ 选填 │ │
│ 描述 │ 选填 │ │
│ 仓库地址 │ 选填 │ │
│ 图片路径 │ 选填 │ /i/sha.ext 或 http(s)://URL │
│ 市场价USD │ 选填 │ 数值 │
│ 市场参考链接 │ 选填 │ │
│ 建议售价USD │ 选填 │ 数值 │
│ 供应商 │ 选填 │ 供应商名称(需已存在于系统) │
├─────────────┼────────┼──────────────────────────────────────────────┤
│ 以下为香水专属 │ │ product_type 以 xiang_shui 开头时生效 │
├─────────────┼────────┼──────────────────────────────────────────────┤
│ 品牌 │ 选填 │ │
│ 系列 │ 选填 │ │
│ 性别 │ 选填 │ │
│ 前调 │ 选填 │ │
│ 中调 │ 选填 │ │
│ 后调 │ 选填 │ │
│ 介绍 │ 选填 │ │
│ 推荐链接1标题 │ 选填 │ │
│ 推荐链接1 │ 选填 │ │
│ 推荐链接2标题 │ 选填 │ │
│ 推荐链接2 │ 选填 │ │
└─────────────┴────────┴──────────────────────────────────────────────┘
{
"success": true,
"inserted": 15, // 新创建的产品数
"updated": 8, // 更新的已有产品数
"skipped": 2, // 跳过的行数(SKU为空/供应商不存在/分类未知等)
"errors": [ // 最多返回20条错误信息
"第 5 行:未知供应商\"不存在的供应商\"(请先在系统字典中创建)",
"第 12 行:未知产品分类\"错误分类\""
]
}
/api/export_products
导出产品Excel
将产品导出为 Excel 文件,列格式与导入模板一致,可直接修改后重新导入。支持 GET 和 POST 两种方式调用。
// GET 方式
GET /api/export_products?pallet_id=1
// POST 方式(可指定导出特定产品)
POST /api/export_products
{
"pallet_id": 1, // 选填 - 按货盘过滤
"ids": [101, 102, 103] // 选填 - 仅导出这些产品ID
}
// 返回 Excel 文件下载
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Disposition: attachment; filename="货盘清单_20260602_143025.xlsx"
// Excel 包含所有列: 编号, SKU, SKU_WN, 产品名称, 产品分类,
// 价格, 库存, 规格, 描述, 仓库地址, 图片路径,
// 市场价USD, 市场参考链接, 建议售价USD, 供应商,
// 品牌, 系列, 性别, 前调, 中调, 后调, 介绍,
// 推荐链接1标题, 推荐链接1, 推荐链接2标题, 推荐链接2
图片管理接口
/api/ngs/upload
上传图片
上传图片文件到服务器,返回稳定的图片路径 /i/<sha256>.<ext>。该路径可用于产品 image_path 字段和货盘默认图字段。系统按 SHA256 去重,相同文件不会重复存储。
Content-Type: multipart/form-data
file: 图片文件 — 必填
支持格式: jpg, jpeg, png, gif, webp
// 成功
{
"success": true,
"image_path": "/i/a1b2c3d4e5f6...abc.jpg"
}
// → 将 image_path 填入产品创建/更新请求, 或 Excel 的「图片路径」列
// 失败 - 缺少文件
{"error": "缺少文件"} // HTTP 400
推荐调用流程
批量导入产品(含图片)的标准流程:
POST /api/suppliers
创建供应商(导入时按名称匹配,必须先创建)
POST /api/pallets
创建货盘,获取 pallet_id
POST /api/ngs/upload
上传产品图片,获取 image_path(每张图一次)
POST /api/upload_products
导入 Excel(pallet_id + Excel 文件),「图片路径」列填步骤3返回的 image_path
可用 Skills
选择一个 Skill 查看详情
请从左侧列表选择一个 Skill 查看其内容。
极其危险的操作
此操作将永久移除所有选定的记录,无法通过任何方式撤销。请务必确认您已经备份了重要数据。
最后一次确认
请输入 DELETE 以确认销毁数据
v2026.06.21.009