From e4679b06c51e3781c2fc03150fac1af25d2d4721 Mon Sep 17 00:00:00 2001 From: KVM-2 dsh agent Date: Tue, 22 Sep 2026 11:42:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=B8=85=E5=8D=95=EF=BC=9A?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E3=80=8A=E4=BA=A7=E5=93=81=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E6=80=BB=E6=B8=85=E5=8D=95=E3=80=8B=EF=BC=88?= =?UTF-8?q?830=20=E8=A1=8C=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 源资料/中台/平台三层字段口径,四类硬证据: - 店小秘官方导入模板 61 列(/tmp/dxm-Template.xlsx 表头) - 平台接口 raw 字段全集(速卖通191/TikTok167/Shopee141/Walmart35/Ozon10+45/SHEIN48/Lazada61;妙手 TikTok84/Shopee74/Temu73/SHEIN61) - 真·1688 源字段(new20-raw/*.html 的 window.context 模块) - 8 个平台建品脚本落点(逐字段行号)+ 跨平台字段名对照表 含四项口径更正(unitWeight=kg vs weight=g、MOQ 可得、Ozon 无建品脚本、规则库未接线)与硬编码待改清单。 --- 产品数据字段总清单.md | 830 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 830 insertions(+) create mode 100644 产品数据字段总清单.md diff --git a/产品数据字段总清单.md b/产品数据字段总清单.md new file mode 100644 index 0000000..c4094f4 --- /dev/null +++ b/产品数据字段总清单.md @@ -0,0 +1,830 @@ +# 跨境电商产品数据字段总清单 + +> 生成:2026-09-22 · 作者:KVM-2 DSH agent · 用途:作为**唯一字段口径表**,供建品脚本、数据同步、字段补齐、跨平台映射共用。 +> +> **证据优先级**(本文件所有条目都按此分级,未标注的即"未验证"): +> - ★★★ 官方/接口事实:店小秘官方导入模板、平台列表接口返回的真实字段、库内真实文档 +> - ★★ 代码事实:线上脚本读写过的 store 路径 / selector / 单位换算 +> - ★ 文档事实:需求文档、技能笔记、注释 +> - ❓ 待确认:仅为推测或来源冲突 +> +> 主要来源:`listing-spec/建品质量需求.md`(需求单一事实源)、`~/ds·/skills/dianxiaomi-multiplatform-listing`、`/tmp/dxm-Template.xlsx`(官方模板)、`products.listings`(库内 5.8 万条真实文档)、`~/1688-xborder/*.csv`(源资料)、`~/<平台>建品/*.mjs`(线上脚本)。 + +--- + +## ⚠ 0. 先处理:妙手同步已"静默失败",但监控报 OK + +`logs/miaoshou-20260922-031701.log`(最新一轮 03:17): + +``` +Temu全托管 waitPublish ✗ pddkj/waitPublish: 您的授权已经过期,请重新登录 +…(22 个平台全部同一错误) +== 完成 49.5s 错误 22 +``` + +而 `logs/last-status.txt` 写的是 `miaoshou=OK(库内 waitPublish 文档=2870/在线 55462,…)`。 + +**机制**:脚本对每个平台 catch 异常后继续跑,`sync_all.sh` **只看退出码** → cookie 过期导致 **0 新增**,但库内旧数据非 0,于是报 OK。 +**后果**:巡检判据「文档数=0」抓不到这一类故障;妙手的 2870 / 55462 是**旧快照**,不是当前值。 +**修法**:妙手登录态来自 `/tmp/dxm7` profile(`msp_session.py`,CDP 9223)→ **需重新登录**;并建议给 `sync_all.sh` 增加"本轮新增=0 且错误数>0 → 判 FAIL"的判据(现在只看退出码)。 + +--- + +## 0. 三层数据模型(先看清字段在哪一层) + +| 层 | 载体 | 字段量级 | 本文件章节 | +|---|---|---|---| +| **L1 源资料**(选品/采集) | `~/1688-xborder/*.csv`、1688 详情页、内网货盘 | 12–18 列 + 1688 原始 HTML | §1 | +| **L2 中台**(店小秘 / 妙手) | Pinia store、官方导入模板、库内 `raw` | 店小秘官方模板 61 列;接口 raw 10–191 字段 | §2 §3 §4 | +| **L3 平台**(发布后回读) | 平台接口 `/api/<模块>Product/pageList.json` | 同上(店小秘把平台字段透传进 raw) | §4 §11 | + +**关键认知**:店小秘的 `raw` 字段 ≈ 平台字段超集(速卖通 191 个),我们**归一化了 17 个**用于统计,其余全量躺在 `raw` 里。所以要补任何字段,**先去 `raw` 里找,不要重新爬**。 + +--- + +## 1. L1 源产品资料字段(选品与采集层) + +### 1.1 三套 CSV 的真实表头 ★★★ + +| 用途 | 文件 | 列数 | 字段 | +|---|---|---|---| +| 选品候选(1536 行) | `candidates-20260914.csv` | 17 | `sku, pid, title_zh, title_en, cost_cny, weight_kg, est_price_usd, est_margin_pct, score, offer_1688, offer_id, supplier, kb_status, pool_status, stock, image, category` | +| 富化核验(60 行) | `enriched-20260914.csv` | 12 | `offer_id, sku, cost_cny_in, title_1688, price_min_cny, price_range_raw, supplier_1688, moq, weight_raw, image_url, valid, note` | +| 终选(含来源与克重) | `final-candidates-20260914.csv` | 14 | `offer_id, sku, title, price_1688_cny, pool_cost_cny, weight_g, weight_source, supplier_1688, est_price_usd, est_margin_pct, category, offer_url, image, pool_status` | +| 上架包(含俄语文案与定价链路) | `t1-上架包.csv` | 18 | `货号, 品名, offer_id, 供应商, 成本CNY, 克重g, 头程CNY, 公式价KZT, 首发价KZT, 全链路成本KZT, 保本价KZT, 每单利润KZT, 首发毛利pct, 公式价毛利pct, WB参照, 俄语标题, 俄语卖点, 俄语关键词` | + +### 1.2 ★ 真·1688 原始字段(`window.context`,最硬证据) + +> **更正**:上一版把"源资料"等同于 `~/1688-xborder/*.csv`,那是**下游产出**,不是原始采集。 +> 真·原始数据在 `~/1688-xborder/new20-raw/*.html`(17 个 500–676KB 详情页,BDPM 抓取), +> 字段内联在 `window.context.result.data.<模块>.fields` 里。涉及模块: +> `productPackInfo` · `priceModel` · `skuInfoMap` · `offerBaseInfo` · `od_product_description` · `od_size_chart` · `consign` · `shippingServices` · `frontSellerMemberModel` · `offerSign` + +**基础信息** +| 键名 | 语义 | 单位/格式 | 可得性 | +|---|---|---|---| +| `offerId` | 1688 商品 ID | 数字串 | ✅ 17/17 | +| `` / `subject` | 商品标题 | 中文 | ✅ 17/17 | +| `featureAttributes["货号"].value` | 货号/商家编码 | 文本 | ✅ 14/17(常与 `skuInfoMap.specAttrs` 同值) | +| `priceModel.currentPrices[].price` | 阶梯价 | **¥** | ✅ 17/17 | +| `priceModel.currentPrices[].beginAmount` | **起订量 MOQ** | 整数 | ✅ 17/17(首档即 MOQ) | +| `priceModel.currentPricesWithOnePiece[]` | 一件代发价 | ¥ | ✅ | +| `originalPricesWithoutPromotion[]` / `discountPrice` | 原价/折后价 | ¥ | ✅ | +| `skuPriceScale` | 价格区间串 | `"2.80-3.50"` | ✅(→ CSV `price_range_raw`) | +| `canBookCount` | 可订库存 | 整数 | ✅(值常夸张,如 `99985537`) | +| `saledCount` | 销量 | 整数 | ✅(可能虚高) | +| `postCategoryId` / `topCategoryId` | 1688 类目 | 整数 | ✅ 但**不可直接映射平台类目** | + +**图片(全外链 `cbu01.alicdn.com`)** +| 键名 | 语义 | 说明 | +|---|---|---| +| `imageList[].fullPathImageURI` | **主图原图** | 直接可用 | +| `imageList[].imageURI` | 主图相对路径 | 需拼域名 | +| `imageList[].{searchImageURI,size220x220ImageURI,size310x310ImageURI,summImageURI}` | 各尺寸缩略变体 | 还原规则见 `fetch_1688_imgs.py:19-27` | +| `od_product_description.fields.detailUrl` | **详情图容器** | ⚠ 是外链 JS bundle(`itemcdn.tmall.com/1688offer/icoss<hash>`),**必须二次抓取** | +| `valueImageUrl`(规格/变种图) | 变种图 | ❌ **17 个样本非空 = 0** → 变种图源头拿不到 | +| `cbu01.alicdn.com/cms/upload/*` | 页面小图标 | ⚠ 必须滤掉(不是商品图) | + +**物流(重量/尺寸)—— 单位是雷区,见 §1.5** +| 键名 | 语义 | 单位 | 可得性 | +|---|---|---|---| +| `productPackInfo.fields.unitWeight` | 商品件重 | **千克 kg** | ⚠ 11/17 有值,**6/17 为 `0`(未填≠零重)** | +| `productPackInfo.fields.pieceWeightScale.pieceWeightScaleInfo[].weight` | 单件重量 | **克 g** | ✅ 15/17 | +| `…pieceWeightScaleInfo[].length/width/height` | 长/宽/高 | **厘米 cm** | ⚠ 常为 `0.0`(9/17 全零) | +| `…pieceWeightScaleInfo[].volume` | 体积 | **cm³** | ✅ 有值时正确 | +| `…pieceWeightScaleInfo[].{sku1,sku2,skuId}` | 变体值/SKU ID | 文本/整数 | ✅ | +| `…columnList[].label` | 表头定义 | `长(cm)`/`宽(cm)`/`高(cm)`/`体积(cm³)`/`重量(g)` | ✅ **单位口径的权威来源** | +| `freightInfo.unitWeight` / `shippingServices.fields.unitWeight` | 运费重量 | kg | ✅ 与 `productPackInfo` 同值 | + +**供应链** +| 键名 | 语义 | 可得性 | +|---|---|---| +| `companyName` | 供应商公司全称 | ✅ 17/17 | +| `sellerLoginId` | 供应商店铺名 | ✅(→ CSV `supplier_1688`) | +| `sellerUserId` / `sellerMemberId` | 供应商 ID | ✅ | +| `winportUrl` | 供应商旺铺 | ✅ | +| `featureAttributes["产地"].value` | **产地** | ✅ 9/17,**只到省市**(义乌/金华/浙江/广州/莆田/河北) | +| `featureAttributes["是否进口"]` | 是否进口 | ✅ 4/17(实测全"否") | +| `<span class="location">` | 发货地 | ⚠ 仅 HTML 文本,不在 JSON | +| `deliveryLimitText` | 发货承诺 | ✅(如"承诺48小时发货") | +| `featureAttributes["主要下游平台"/"主要销售地区"]` | 渠道/地区 | ✅ 6–7/17 | + +**属性与变种** +- 统一容器 `featureAttributes[] = {fid,name,value,values,vids,outputType,isSpecial,…}` +- 实测属性名(按出现文件数):`货号`(14) `品牌`(13) `是否跨境出口专供货源`(12) `材质`(9) `产地`(9) `有可授权的自有品牌`(8) `颜色`(7) `上市年份/季节`(7) `处理工艺`(6) `图案`/`流行元素`/`适用送礼场合`(5) `风格`/`包装`/`生产编号`(3) `尺码`/`型号`/`规格`(1–2),另有 80+ 类目长尾属性 +- 变种:`skuInfoMap` / `skuInfoMapOriginal` ✅ 17/17,值 `{specId,saleCount,canBookCount,specAttrs,priceAmount,skuId,isPromotionSku}`;`isSkuOffer:true` 16/17 + +**其他** +| 项 | 状态 | +|---|---| +| 尺码表 `od_size_chart` | ✅ 模块存在,尺码图需从中提取 | +| 平台评分/评价数 | ❌ **1688 详情页不存在**(评分只在需求侧 WB/Ozon 有) | +| EAN / UPC / 条码 | ❌ **全页 689 个 JSON 键无任何 barcode/upc/ean** | + +### 1.2b 建品输入包(下游包,**不是源资料**) + +`~/<平台>建品/*_input.json`(46–48 项,顶层键 = offer_id),每项只有 **11 个字段**: +- `walmart建品/wm_input.json`:`title, bullets, keywords, imgs, weight, ean, pc, cat_index, cat, price_usd, weight_lbs` +- `tiktok建品/tk_input.json`:`title, bullets, keywords, imgs, cost, weight, price_cny, price_myr, guess, cat_kw, cat_fb` + +⚠ **`weight` 是硬编码三档 `100/130/10`,不是实测值**(`tk_input.json` 的 `guess` 字段字面写着 `'cost~,w~'` 自认是猜的)。 +⚠ 全量口径:`最终开品清单.csv` 的 `weight_src` 分布 = `占位100g` **213** 行 vs `L2实核` **20** 行 → **只有 8.6% 的重量是真核过的**。 + +### 1.3 源资料字段语义归并(建品脚本实际消费的) + +| 归一字段 | 脚本里的名字 | 语义 | 单位 | 说明 | +|---|---|---|---|---| +| 货源 ID | `offer_id` / `oid` | 1688 商品 ID | — | 唯一键;来源 URL = `https://detail.1688.com/offer/<oid>.html` ★★ | +| 货号 | `sku` | 我方货号 | — | 平台 SKU 由它派生(如 `WM-<oid>`) | +| 标题 | `IN.title` / `it.title` / `title_1688` / `title_en` | 商品标题 | — | 1688 原文(中文/英文两版) | +| 卖点 | `IN.bullets` / `it.bullets` | 要点列表 | — | 描述与 keyFeatures 的原料 | +| 关键词 | `IN.keywords` / `it.keywords` | 搜索词 | — | 逗号分隔;TikTok 取前 10 个 ★★ | +| 类目猜词 | `IN.cat_kw` / `it.cat_kw` | 类目匹配关键词 | — | ⚠ 类目靠猜是已知缺陷(需求 §3.1 #1) | +| 元卖 | `IN.sp_kw` / `IN.sp_fb` | Shopee 关键词/回退 | — | Shopee 专用 | +| 成本 | `IN.cost` / `it.cost` / `cost_cny` / `pool_cost_cny` | 进货成本 | CNY | 定价模型输入 | +| 1688 价 | `price_min_cny` / `price_1688_cny` / `price_range_raw` | 供货价 | CNY | `price_range_raw` 是原始区间串 | +| 重量 | `IN.weight` / `it.weight` / `weight_g` / `weight_kg` / `weight_raw` | 商品重量 | **口径不一,见 §1.5** | 🔴 最大雷区:源头 kg/g 两个字段并存;下游 `weight` 多为硬编码占位 | +| 图片 | `IN.imgs` / `it.imgs` / `image` / `image_url` | 主图+详情图混装 | URL 数组 | ⚠ 混装,必须过 `filterProductImages()` ★★;详情图需二次抓取 | +| 供应商 | `supplier_1688` / `supplier` | 供应商名 | — | 产地字段的来源(只到省市) | +| 起订量 | `moq` / `priceModel.currentPrices[].beginAmount` | 最小起订 | 件 | ⚠ **实际可得**(旧文档称"取不到"是错的);但 L2 CSV 的 `moq` 列**全空**是脚本没提 | +| 库存 | `stock` / `canBookCount` | 1688 库存 | 件 | 值常夸张,仅方向性 | +| 定价结果 | `est_price_usd, est_margin_pct, score` + `公式价KZT/保本价KZT/…` | 定价与经济性 | USD/KZT | 选品阶段算出 | +| 多语言文案 | `俄语标题/卖点/关键词` | 本地化文案 | — | 目前仅俄语(Ozon/WB 线) | + +### 1.4 源资料的**结构性缺口**(L1 拿不到、必须人工或另找) + +| 缺口 | 影响的平台 | 现实做法 | 证据 | +|---|---|---|---| +| **品牌** | 全平台 | 一律 `无品牌`;**源头 `品牌` 属性 13/17 有值但不可信**(常为 `自主`/`其他`/`否`,或供应商乱填的品牌名,发布前必须清) | ★★★ | +| **EAN/UPC/ISBN** | Temu/Walmart/速卖通 SKU | 全页 689 个 JSON 键**无任何 barcode/upc/ean** → 走自家 EAN-13 台账(`69803093` 段),用号必须落 S03 台账 | ★★★ | +| **原产国 / 产地** | Walmart(Country of Origin)、速卖通(产地必填) | 源头 `产地` **只到省市**(义乌/浙江/金华/广州/莆田/河北),`是否进口`=否 → 默认 `China` | ★★★ | +| **包装尺寸** | Walmart(inch)、Temu、Shopee | ⚠ **9/17 样本长宽高全为 0.0**;建品 CSV 里的 `15/10/3` 是**人工默认值**,与 1688 源无对应关系。真值须实测或问供应商 | ★★★ | +| **发运重量** | 全平台 | `unitWeight` 是**单件属性值**,未必含外包装(实测有 `1g` 的离谱值)→ 代码统一加 `--weight-buffer 1.3` | ★★★ | +| **净重 vs 毛重** | Temu(净重必须<重量) | 源头只有件重,净重需估算或人工 | ★★ | +| **规格/变种图** | TikTok/速卖通/Walmart 变参图 | ❌ `valueImageUrl` **17 个样本非空 = 0** → 无自动来源,需从主图/详情图裁切 | ★★★ | +| **详情图** | Shopee/Temu/速卖通 | **不在主 HTML 里**:`od_product_description.fields.detailUrl` 是外链 JS bundle,必须二次抓取 | ★★★ | +| **MOQ** | 铺货一般不用 | ✅ **其实拿得到**(`priceModel.currentPrices[0].beginAmount`);旧文档"取不到"的说法源于早期只读属性表文本 | ★★★ | +| **HS / ТН ВЭД 编码** | Ozon/Walmart | 源头无此字段 → 走自有 HS 字典(中国 10 位 12,030 / ЕАЭС 9 位 12,937 / 国际 6 位 5,613) | ★★ | +| **平台类目映射** | 全平台 | 1688 `postCategoryId/topCategoryId` **不可直接映射**平台类目树 | ★★★ | +| **高关注化学品 / 加州65** | 速卖通、Walmart | 填 `none`(速卖通写死 id `23399591357`) | ★★ | +| **产品说明书文件** | 速卖通(部分类目强制) | 无来源 → 需生成或跳过该类目 | ★ | +| **视频** | 速卖通、TikTok | 无来源 → 需图生视频或人工 | ★★ | +| **平台评分/评价数** | 选品参考 | ❌ 1688 详情页**无评分字段**(评分只在需求侧 WB `feedbacks/rating`、Ozon `reviews/rating`) | ★★★ | +| **供应商可用性** | 全平台 | 1688 链接有效率:`inactive` 品 **25%**、`active` 品 **62%** → 必须实核,失效标 `invalid`,不许编数据 | ★★ | + +### 1.5 🔴 重量单位口径(本项目最贵的一类事故) + +**同一页有两条重量、两种单位,读错差 1000 倍:** + +| 字段 | 单位 | 说明 | +|---|---|---| +| `productPackInfo.fields.unitWeight` | **千克 kg** | 如 `0.010` = 10g | +| `…pieceWeightScaleInfo[].weight` | **克 g** | 同模块 `columnList.label` 直接写 `重量(g)` | +| `…length/width/height` | **厘米 cm** | label `长(cm)`/`宽(cm)`/`高(cm)` | +| `…volume` | **cm³** | label `体积(cm³)` | +| L2 CSV `weight_raw` | 文本 | 形如 `重量(g)=75`(来自属性表文本,不是 JSON) | + +**17 样本交叉验证结果**:**8 个一致 / 1 个冲突 / 6 个 `unitWeight=0`(未填)/ 2 个无包装表**。 +🔴 冲突样本 `800850312791`:`unitWeight=0.001`(1g) vs 包装表 `50g`,**差 50×**。 + +**三个必须记住的坑** +1. **`unitWeight` 是 kg 不是 g**。技能 `1688-cross-border-sourcing/SKILL.md:55` 只写"重量单位是克"(那句针对的是属性表文本),照着读 `unitWeight` 会把 10g 当 0.010g。 +2. **`unitWeight = 0` 表示"未填",不是"零重"**(6/17)。`ozon_unit.py:86` 直接 `weight_g/1000.0` 而不判 0 → 会算出零运费、虚高毛利。 +3. **历史事故**(该技能原文):① "数值>50 才除 1000" → 10g 当 10kg,**毛利 -2381%**;② 改成"数值<5 就当 kg" → `重量(g)=3` 又变 3000g。**正确做法是单位优先,其次按列语义兜底**(实现见 `ru_market.py:215-236`)。 + +### 1.6 口径冲突清单(不同脚本/文档互相打架,接线前必须裁决) + +| 冲突 | A 说法 | B 说法 | 裁决 | +|---|---|---|---| +| 重量启发式 | `select_candidates.py:95`:">50 视为 g"(面向 Mongo `package_weight`,本身是 kg) | `ru_market.py:215-236`:单位优先,1688 详情无单位时**默认按 g** | 面向不同数据源;**同一合并表里两列并存**(`weight_raw`=g / `weight_kg_pool`=kg),套错列就出事故 | +| 抓取正路 | `1688-cross-border-sourcing`(英):详情页**唯一可靠是 Desktop CDP**,Firecrawl/Jina/直连都不行 | `1688-crossborder-sourcing`(中):**BDPM curl 才是正路**(实测 4/4 成功、124–133KB),比派浏览器 agent 可靠 | 实际 `new20-raw/*.html` 是 500–676KB 正常页,**与 BDPM 路线吻合** | +| MOQ 可得性 | 两个技能均称"取不到/不可靠" | raw 页 `beginAmount` 出现 20 次 | **B 正确**,规格源于早期实现缺失 | +| 库名 | 英技能写 `premiumproducts.products` | 中技能与 `premiumproducts-db` 写 `productpool1.products`(221,874) / `premiumproducts.products` | 未裁决 ⚠ | +| 失效引用 | 英技能引用 `~/.hermes/scripts/1688_scrape_cdp.py` 与 `references/*` | — | **本机不存在**(该技能只剩单文件)⚠ | + + +--- + +## 2. 店小秘官方导入模板字段(61 列,权威口径)★★★ + +来源:`/tmp/dxm-Template.xlsx`(官方 Template,`build_dxm_import.py` 直接读取表头,不手抄)。 +表头形如 `*ParentSKU\n(必填)`,代码用 `core()` 归一化后匹配——**坑:直接用短名匹配会全部取空,文件表面看不出必填列全空**(脚本注释原话)。 + +| 分组 | 列号 | 字段(官方表头) | 必填 | +|---|---|---|---| +| **标识** | 1 | `*ParentSKU` | ✅ | +| | 2 | `*SKU` | ✅ | +| | 7 | `UPC` | | +| | 8 | `landingPageUrl` | | +| **文案** | 3 | `*产品标题` | ✅ | +| | 4 | `*产品描述` | ✅ | +| | 5 | `产品标签` | | +| | 44 | `英文申报名称` | | +| | 45 | `申报的本地名称` | | +| **品牌/属性** | 6 | `品牌` | | +| | 10 | `颜色` | | +| | 11 | `尺寸值` | | +| | 9 | `msrp` | | +| **来源** | 12 | `来源url` | | +| **价格** | 13 | `*价格(USD)` | 美元店铺必填 | +| | 14 | `*价格(CNY)` | 人民币店铺必填 | +| | 15 | `*运费(USD)` | 美元店铺必填 | +| | 16 | `*运费(CNY)` | 人民币店铺必填 | +| | 49 | `申报价值(USD)` | | +| **库存** | 17 | `*库存量` | ✅ | +| **图片** | 18 | `主图(URL)地址` | | +| | 19 | `变种图(URL)地址` | | +| | 20–38 | `附图1…附图19(URL)地址` | | +| | 39 | `附图20-100(URL)地址` | | +| **物流/海关** | 43 | `重量(g)` | | +| | 46/47/48 | `包裹长度/宽度/高度(cm)` | | +| | 42 | `海关HS编码` | | +| | 50 | `件数` | | +| | 51 | `发货地区代码` | | +| **合规** | 52–55 | `是否含粉末/液体/电池/金属` | | +| | 56 | `加州65号提案警告类型` | | +| | 57–61 | `加州65号提案化学品名称1..5` | | +| **其他** | 40 | `备注` | | +| | 41 | `产品状态` | | + +> 注:这份模板偏 **Walmart/通用** 口径(有 UPC、msrp、landingPageUrl、加州65)。它是"产品级"字段;**平台级的必填项不在这张表里**,必须走各平台添加页(见 §4)。 + +--- + +## 3. 跨平台通用产品主档(语义归一,建议内部统一命名) + +这是"我们应该在内部统一维护的最小完备集"。`必要性` 列的 ⭐ 表示"几乎所有平台都要"。 + +### 3.1 标识与来源 +| 字段 | 单位/格式 | 来源 | 必要 | 备注 | +|---|---|---|---|---| +| `oid` | 字符串 | 1688 | ⭐ | 主键;来源 URL 由它拼 | +| `sku` / `parentSku` | 字符串 | 我方 | ⭐ | 店小秘模板列 1、2 | +| `sourceUrl` | URL | 1688 | ⭐ | 速卖通 #9、Walmart #1 都要求 ★★ | +| `ean` / `upc` / `isbn` | 13 位 | EAN 台账 | 平台相关 | Walmart 要 **ISBN**(不是 UPC);Temu 要 EAN ★★ | +| `hsCode` | 字符串 | 人工/类目库 | | 模板列 42 | +| `platformProductId` | 字符串 | 平台回读 | | 发布后才有 | + +### 3.2 文案 +| 字段 | 上限 | 规则 | 备注 | +|---|---|---|---| +| `title` | Walmart **100**、Temu **120** | 过 `filterTitle()`;窄义词**同义替换**(策略 B)+ 长度兜底 | ★★ | +| `bullets` | — | 逐条过 `filterTitle` | Walmart `keyFeatures`、TikTok 描述 | +| `keywords` | TikTok 取前 **10** | — | | +| `description`(HTML) | — | **必须含 `<img>` 产品图**(速卖通 #7/TikTok #3/Temu #3) | ★★ | +| `mobileDescription`(HTML) | — | 无线端单独字段(Temu `describeInfoData.mobileDetail`) | ★★ | +| `searchTerms` | — | TikTok 独立字段 | ★★ | + +### 3.3 交易 +| 字段 | 单位 | 规则 | 备注 | +|---|---|---|---| +| `price` | 平台币种 | 见 §5 币种 | ★ | +| `原价/originalPrice` | 同上 | Ozon 要求 **售价 < 原价**,改价必须同时抬原价 | ★★ | +| `declaredValue` | 同上 | **与售价一致**(速卖通 #6) | ★★ | +| `stock` | 件 | — | ⭐ | +| `currency` | ISO | Ozon/TikTok/Shopee 各不同 | ★★ | +| `msrp` | USD | 模板列 9 | | +| `运费` | USD/CNY | 模板列 15/16;速卖通走运费模板 | ★ | +| `promotionPrice` | — | Walmart 字段 | | + +### 3.4 物流与包装 +| 字段 | 单位 | 规则 | 备注 | +|---|---|---|---| +| `weight` | 见 §5 | 源克 → 平台单位,**必须显式换算** | ★★ 曾把 130g 写成 130KG | +| `netWeight` | 同上 | Temu **净重必须 < 重量** | ★★ | +| `packageLength/Width/Height` | cm 或 inch | **不得用重量推算**;Walmart 转英寸 | ★★ | +| `shippingWeight` | lbs | Walmart 专用 | ★★ | +| `freightTemplate` / `promiseTemplate` | id | 速卖通 | ★★ | +| `warehouse` / `发货地区代码` | — | TikTok/Walmart | ★★ | +| `含粉末/液体/电池/金属` | bool | 模板列 52–55 | | + +### 3.5 图片与视频 +| 字段 | 格式 | 规则 | +|---|---|---| +| `mainImages[]` | 外链数组 `{url,imgUrl,name,width,height(,checked)}` | 上传前过 `filterProductImages()`(剔详情图)★★ | +| `variantImages[]` | 同上 | **每个变种只放自己的图,不能串图**(TikTok #4/Walmart #7/速卖通 #8)★★ | +| `mainImage`(单图串) | `\|` 分隔 | Walmart/Temu 的落库形态 ★★ | +| `squareImage` | 单图 | SHEIN 方图字段 ★★ | +| `materialImage` / `packageImages` | 数组 | Temu 专用 ★★ | +| `sizeChartImage` | 单图 | Temu 第 4 张 = **cm/inch 双标尺寸图** ★★ | +| `whiteBgImage` | ≥800×800 | 内网 FlairGS `/api/white-bg`,3.6s,可用 ★★ | +| `sceneImage` | 3:4 | flux 可用但构图不合格;forge 不可用 ★★ | +| `video` / `videoUrl` | URL | 速卖通/TikTok 有槽位,当前未填 ★ | + +### 3.6 变种 +| 字段 | 说明 | +|---|---| +| `variantTheme` | 变种主题(颜色/尺码);TikTok 还要求**主题图** ★★ | +| `option1/2/3` + `option1Value/...` | TikTok raw 字段命名(最多 3 个变种维)★★ | +| `skuDataList[]` | Temu 的 SKU 行:`length,width,height,weight,netWeight` + 货号/EAN/价格 ★★ | +| `variantList[]` | 通用:`sku, price, salePrice, quantity, imageList, weight, packageL/W/H` ★★ | +| `saleProp` / `propertyInfo` | Lazada/Shopee 变种属性 ★★ | + +### 3.7 合规 +| 字段 | 取值 | 来源 | +|---|---|---| +| `brand` | **`无品牌`** | 硬要求 ★★ | +| `isNoBrand` | `true` | Walmart **独立开关**(`walmartAttrStore.isNoBrand`),光写 brand 不生效 ★★ | +| `countryOfOrigin` | `China` | Walmart `Country of Origin-Substantial Transformation` ★★ | +| `manufactureId` / `产地` | 供应商产地或固定 id | 速卖通写死 `9441741844`(待改)★★ | +| `高关注化学品` | `none` | 速卖通写死 id `23399591357`(待改)★★ | +| `productManual` | 文件 | 速卖通类目相关强制 ★ | + +### 3.8 店铺与类目 +| 字段 | 说明 | +|---|---| +| `shopId` | 店铺;TikTok/Walmart/Ozon 用下拉 | +| `siteIds[]` / `sites` | TikTok 多站点(全选后 `["5880928","5880883","5880945"]`)★★ | +| `categoryId` / `fullCid` | 类目;**必须与店铺授权类目对应**,不得猜 ★★ | +| `categoryName` / `nodePath` | 展示名/路径 | +| `attributes` / `productAttributes` | 类目属性(各平台结构不同) | +| `sizeChart` / `sizeTemplateId` | 尺码表 | + +--- + +## 4. 各平台字段对照(店小秘侧) + +### 4.1 平台清单与规模 ★★★(库内真实数据,`products.listings`) + +**店小秘(source=dianxiaomi)** + +| 平台 | 接口模块 | raw 字段数 | 待发布 | 在线 | 发布失败 | +|---|---|---:|---:|---:|---:| +| 速卖通 | `smtProduct` | **191** | 293 | 1,682 | — | +| 速卖通全托管 | `smtProduct`(cus) | 126 | 34 | 185 | 2 | +| Ozon | `ozonProduct` | 10 + `products[]` 45 | 52 | 20,415(组 2,593) | — | +| TikTok | `tiktokProduct` | **167** | — | 4,257 | — | +| Shopee-全球 | `shopeeProduct` | **141** | 1 | 3,577 | — | +| Walmart | `walmartProduct` | 35 | 48 | 2,090(组 1,068) | 6 | +| SHEIN | `sheinProduct` | 48 | — | 710 | — | +| Lazada | `lazadaProduct` | 61 | — | — | — | +| (Joom / aliChoice) | — | — | 未接入同步 | — | — | + +**妙手(source=miaoshou)** + +| 平台 | key | raw 字段数 | 待发布 | 在线 | +|---|---|---:|---:|---:| +| Temu 全托管 | `pddkj` | 73 | 45 | **55,462** | +| TikTok | `tiktok` | 84 | 2,744 | — | +| Shopee | `shopee` | 74 | 37 | — | +| SHEIN | `shein` | 61 | 44 | — | +| Ozon | `ozon` | — | 采集箱 1,555(未发布) | — | + +### 4.2 平台字段落点(写入路径)★★ + +> 落点 = Pinia store 路径 或 DOM selector。**改 store ≠ 落库**,见 §10。 + +**Walmart**(保存体是 **zip 的 multipart**,内含 `walmartSave.txt`) +| 字段 | 落点 | +|---|---| +| Product Name | `walmartProductStore.formState.productName` | +| 产品标识符类型 | `walmartProductStore.formState.productIdType` = **`ISBN`**(原 UPC,已改) | +| 产品标识符值 | `walmartProductStore.formState.productId` | +| 品牌 | `walmartAttrStore.formState.brand` = `无品牌`;**并** `isNoBrand=true` + 点 `.ant-checkbox-wrapper` | +| 价格/库存/运输重量 | `walmartPriceShippingStore.formState.{price, inventory, shippingWeight}`(重量 **lbs**) | +| 描述/keyFeatures | `walmartDescStore.formState`(HTML bullets) | +| 主图 | `walmartImgStore.formState.mainImage`(**必须 hover→「网络图片」贴 URL**)⚠ 当前不落库 | +| 来源URL / Country of Origin | 页面 DOM 字段(已确认存在,待接) | +| 变种 | `basic.hasVariant=false`(**当前被关掉**,需求 #7 要求开启) | + +**Temu** +| 字段 | 落点 | +|---|---| +| productName | `temuAddProductStore.$state.formState.productName` | +| 主图/材质图/包装图 | 同 store `.mainImage / .materialImage / .packageImages` | +| 描述(PC/无线) | `temuAddStore.$state.describeInfoData.{detail, mobileDetail}` | +| 类目 | `temuAddBasicStore.$state.formState.categoryId`(store 直读类目 1038 个) | +| SKU 行 | `temuAddSkuDataStore.$state.formState.skuDataList[]`(`length/width/height/weight/netWeight`) | +| 变种属性 | `temuAddSkuAttrStore.$state.formState`(用 `.theme-value-add` 手动输值+添加,改 store 无效) | +| 其他 | `temuAddOtherStore.$state` | +| ⚠ 条件必填 | 产地=中国 → **省份必填**;报错层层递进 | + +**TikTok**(价格 **MYR**) +| 字段 | 落点 | +|---|---| +| 店铺/站点 | `tiktokGlobalAddBasicStore.formState.{shopId, siteIds, categoryId}`(多国+复制用「全选」) | +| 标题/关键词/描述 | `tiktokGlobalAddProductStore.formState.{productName, searchTerms, description}`(描述含 `<img>`) | +| 品牌 | `tiktokGlobalAddStore.attrsInfo` = `无品牌` | +| 货到付款 | `tiktokGlobalAddOtherStore.$state.logisticsFormState.isCodOpen = 1`(**不是** `dxFormState`) | +| 主图 | `tiktokGlobalImgStore.formState.mainImage[]` | +| 变种图 | `skuDataList[i].image` / `tiktokGlobalSkuUsImageStore.skuUsImageMap`(**美国站专用**,本店 `isSupportSkuUsImage=false`)⚠ 未完成 | +| 重量/尺寸 | 重量 `setItem('重量')`;尺寸规格三个 input 按 placeholder 长/宽/高(回读 `长=130 宽=78 高=26`) | +| 来源URL | `setItem('来源URL')` = `https://detail.1688.com/offer/<oid>.html` | + +**速卖通**(价格含税;`check_box` 属性值必须是数组) +| 字段 | 落点/说明 | +|---|---| +| 品牌 | 属性:`无品牌` / `NONE(无品牌)` | +| 产地 | 属性 id `9441741844`(**硬编码,待改**) | +| 高关注化学品 | 属性 id `23399591357`(**硬编码**,应 `none`) | +| 图片 | `imageList`,外链对象 `{id,url,name,width,height,imgId,checked}` | +| 描述 | CKEDITOR(PC+无线),需插图 + 规范 HTML | +| 价格/货值 | `零售价`/`货值`(原硬编码 1.99/0.50,须一致) | +| 重量/尺寸 | 原硬编码 `0.02kg` / `10×5×3`(待用 1688 实抓) | +| 运费/服务模板 | `freightTemplateId` / `promiseTemplateId` | +| SKU | `smtProductSkuList[]`(含 `eanCode, skuPrice, skuStock, skuImage, packageWeight…`) | +| 说明书 | `productManual`(类目相关**强制**,缺失会被 `MYJ.message.error` 吞掉) | + +**SHEIN** +| 字段 | 落点 | +|---|---| +| 图片 | `sheinImgStore.formState.squareImage`(方图) + `mainImgData.{multipleSpuImgs, singleSpuImg}` ⚠ **全部写住仍不落库**,见 §10 | +| 类目 | 需**两个规格**(点 `.theme-select-box` 加 `尺寸(Size)`) | +| 顺序 | 必须「规格 → SKU → 尺码表」(加规格会**重建 SKU 行**) | + +**Shopee** +| 字段 | 说明 | +|---|---| +| 列表字段名 | `itemName`(**不是** title) | +| 模式 | 单件模式 `type='single'` 绕开变种 | +| 图片 | `mainImages`(原脚本把主图+详情图全量塞入 → 已加过滤器) | +| 重量 | 字段单位 **KG**,输入是**克** → 必须 `g/1000` | +| 尺寸 | 原用重量推算(`W = weight×1.3`)→ 必须改 1688 实抓 | + +**Ozon** +| 字段 | 说明 | +|---|---| +| 价格 | **CNY**;`variantList[].price`(原价) / `salePrice`(售价),**售价必须<原价** | +| 保存 | 按钮是「保存并移入待发布」 | +| 在线口径 | 返回**合并组**:`productNum/count` 才是子商品数 | + +> ⚠ **Ozon 没有建品脚本**:`~/ozon*` 只有 `ozon定价/`(算价)与 `ozon改价/ozprice_set.mjs`(**只写「价格/原价」两个字段**,入口 `/web/ozonProduct/edit?id=<pid>`,原价 = 售价×1.2 向上取整 2 位,且**唯一有 API 级回读**:`GET /api/ozonProduct/add.json?id=<pid>` → `variantList[].price/.salePrice`)。 +> 全盘 find 无 `ozon建品` 目录 → **Ozon 字段清单无法从代码抽取,要补必须先写脚本**。 + +### 4.3 跨平台字段名对照表 ★★(同一语义,8 个平台叫法完全不同) + +| 语义 | SMT 速卖通 | Shopee | SHEIN | Temu | Joom | aliChoice | Walmart | TikTok | +|---|---|---|---|---|---|---|---|---| +| 标题 | DOM「产品标题」 | `…ProductStore.title` | `sheinAddProductStore.productName` | `temuAddProductStore.productName` | `smtChoiceAddBasicStore.name` | `smtChoiceAddBasicStore.subject` | `walmartProductStore.productName`(+DOM) | `tiktokGlobalAddProductStore.productName` | +| 描述 | CKEditor `setData` | `…descriptionInfo.{descriptionText,descriptionHtml}` | — | — | `smtChoiceAddBasicStore.description` | `smtChoiceAddStore.describeInfoData.detail`+CKEditor | `walmartDescStore.description`(+DOM) | `…AddProductStore.description` | +| 卖点 | 并入描述 | 并入 descriptionText | — | — | 并入 description | 并入 detail | `walmartDescStore.keyFeatures` | `…AddProductStore.keyProductFeatures` | +| 搜索词/标签 | 并入「Keywords:」 | 并入 descriptionText | — | — | `smtChoiceAddBasicStore.tags` | — | — | `…AddProductStore.searchTerms` | +| 价格 | DOM「零售价格」 | DOM「价格」←`price_cny` | `sheinSkuDataStore.skuDataList[i].skcRetailPrice` | `temuAddSkuDataStore…skuDataList[i].suggestedPrice` | `joomAddPriceStore.price` | `smtChoiceSkuDataStore…skuDataList[i].skuPrice` | `walmartPriceShippingStore.price`(+DOM) | SKU 表列「本地展示价」←`price_myr` | +| 供货/成本 | — | — | `…supplyPrice` | `…supplierPrice` | 仅 declaredValue | — | — | — | +| 货值/报关 | DOM「货值」 | — | — | — | `joomAddPriceStore.declaredValue` | — | — | — | +| 库存 | DOM「库存数量」 | DOM「库存」 | `…stockVariety` | (SKU 行无) | `joomAddPriceStore.inventory` | — | `walmartPriceShippingStore.inventory`(+DOM) | SKU 表列「库存」 | +| 重量 | DOM「重量(kg)」+「包装后重量」 | DOM「重量」←`weight` | `…skuDataList[i].weight` | `…weight`/`.netWeight` | — | `…packageWeight` | `walmartPriceShippingStore.shippingWeight`←`weight_lbs`(+DOM 运输重量) | DOM「重量」←`weight` | +| 尺寸 | placeholder 长/宽/高 +「包装后尺寸」 | placeholder 长/宽/高←**重量推导** | `…length/width/height` | `…length/width/height` | — | `…packageLength/Width/Height` | (**未写**;`dimsToInch` 备而未用) | placeholder 长/宽/高←**重量推导** | +| 品牌 | `smtAddAttrStore.dynamicFormData[品牌id]='history-…'` | — | 必填属性兜底 | — | 必填属性兜底 | 必填属性兜底 | `walmartAttrStore.brand`+DOM | — | +| 产地 | `dynamicFormData[产地id]='history-…'` | — | 必填属性选「中国/China」 | `temuAddProductStore.productOrigin='CN'`+`region2Id` | — | 必填属性兜底 | — | — | +| 类目 | `smtAddBasicStore.categoryId`(弹窗) | `input[placeholder="搜索分类名称"]` | 同左→`sheinAddBasicStore.categoryId` | 同左→`temuAddBasicStore.categoryId` | `.ant-select-selector` 可搜索 | 弹窗 | `.ant-select-selector` **可滚动**下拉全等 | 弹窗 | +| SKU/货号 | — | — | `…skcSupplierCode`(`SHEIN-001`) | `…extCode`(`TM-<pid>-<n>`) | `smtChoiceAddBasicStore.parentSku`(`JM-<pid>`) | `…skuCode`(`AC-<pid>-<n>`) | `walmartProductStore.sku`(`WM-<oid>`) | SKU 表列「SKU」(`AM-<oid>`) | +| EAN/UPC | — | — | — | `…skuDataList[i].code`(**自算 EAN-13**) | — | — | `productId`←`ean`,`productIdType` | — | +| 主图 | `smtAddProductStore.imageList` | `shopeeGlobalImageInfoStore.$state.imageInfo.mainImages` | `sheinImgStore.mainImgData.multipleSpuImgs` | `temuAddProductStore.mainImage` | `joomAddImageStore.imageList` | `smtChoiceAddProductStore.mainImage` | `walmartImgStore.mainImage` | `tiktokGlobalImgStore.$state.formState.mainImage` | +| 素材/详情图 | 并入 imageList | 并入 mainImages | — | `.materialImage`+`packageFormState.packageImages` | `.detailImageList[0].images` | — | (`walmartPackStore` 未用) | — | +| 变种/规格 | — | `type='single'`(绕开变种) | `.theme-select-item`+`.sku-option`(**上限 3 规格**) | `.theme-value-add`+`temuAddSkuAttrStore.skuAttrs` | — | 原生 select「SKU分类」 | `hasVariant=false` | 「变种属性」`input[class*="!w-200"]`+「添加」 | +| 来源URL | — | DOM「来源URL」 | — | — | — | — | (已确认存在,待接) | DOM「来源URL」 | +| 物流属性 | `smtAddProductStore.specialProductTypeList`(**直赋**) | — | — | — | — | 报错→`.icon_edit2`→勾「普货」(UI) | — | — | +| 运费/包装 | 运费模板/服务模板/是否原箱/含关税 | — | — | `packageShape=1`、`packageType=0` | `shipping='0'`、`msrp=''` | — | — | — | + +**落点分两类(决定改字段该走 store 还是走 UI)** ★★ +- **① 强一致,可 `$state` 直赋**:SHEIN/aliChoice/Temu 的 SKU 行、SMT 的 `dynamicFormData`/`specialProductTypeList`、**全部平台的图片数组**。 +- **② 必须走 DOM / 真实鼠标**:Temu 变种值(`tmbatch.mjs:57` 注释明写"直改 store 无效")、Temu SKU 预览图(DOM click 打不开下拉)、SMT 描述(必须走 CKEditor 实例)、aliChoice 物流属性(必须走"先保存逼出报错→编辑弹窗")、**所有平台的分类弹窗**。 +- 反例(可直改已建草稿):`tm_fixean.mjs:21-25` 证明编辑页 `skuDataList[i].code` 仍可直赋。 + +### 4.4 硬编码清单(全部"待改",按平台)★★ + +| 平台 | 硬编码项 | +|---|---| +| 速卖通 | 店铺 `4024039`;零售价 **1.99** / 货值 **0.50** / 库存 100;重量 **0.02kg** ×2;尺寸 **10/5/3**(两处);物流属性 `['1983471271:2025103']`;品牌/产地/化学品 id `201512802/9441741844/23399591357`;是否原箱=否;含关税=不含;运费模板默认 `MY beauty 30g+1美金` | +| Shopee | 店铺 `Ljbgkj`;`type='single'`;库存 999;**类目关键词恒回退 `Accessories`** | +| SHEIN | 库存 999;SKU 重量/长/宽/高 **100/200/150/30**;尺码表 **10,18,3,2,18,5**;前缀 `SHEIN-`;价默认 12.90;供货价默认 8.50;**规格上限 3**;产地=中国 | +| Temu | 店铺 ①Alimingpro;省份 `43000000000002`;`productOrigin='CN'`;`packageShape=1`/`packageType=0`;变种 `['Black','One Size']`;SKU 尺寸 **20/15/3**;重量/净重 **100/90**;EAN 前缀 `69803093` + 起始 3448;价默认 19.90;成本默认 10 | +| Joom | 库存 999;`shipping='0'`;`msrp=''`;前缀 `JM-`;价默认 19.90;报关默认 10;**详情图语言=英语**;跳过 pid `676236596821,601964534137` | +| aliChoice | `packageWeight=100`;尺寸 **20/15/3**;前缀 `AC-`;价默认 19.90;`valueFor` 全部兜底;`['单品单件','件/个']`;普货;跳过 pid | +| Walmart | 店铺 `Snowmountain`;`hasVariant=false`;**`productIdType='UPC'`**(但 `IN.ean` 是 13 位 EAN);前缀 `WM-`;品牌默认 **`Generic`**(应为无品牌);库存 999 | +| TikTok | 店铺语义 `AutoMavenShop_MY`;变种默认 `'Default'`;库存 999;描述 style 串;前缀 `AM-`;来源URL 模板 | +| Ozon(改价) | 原价 = 售价 × 1.2,向上取整 2 位 | + +### 4.5 建品脚本的输入源矩阵(谁读哪个文件)★★ + +| 输入文件 | 消费者 | 键 | +|---|---|---| +| `tiktok建品/tk_input.json`(48 条) | TikTok / Shopee / SHEIN / Temu / Joom / aliChoice(**6 个平台共用**) | 实测恰好 11 键:`title, bullets, keywords, imgs, cost, weight, price_cny, price_myr, guess, cat_kw, cat_fb` | +| ↑ **缺键后果** | Shopee 要 `sp_kw`/`sp_fb` → **0/48 命中 → 类目恒 `Accessories`**;无 `ean` → Temu **自造 EAN-13** | — | +| `walmart建品/wm_input.json`(46 条)+ `wm_cats.json`(152 类目) | Walmart | `title, bullets, keywords, imgs, weight(克,未用), ean, pc(未用), cat_index, cat, price_usd, weight_lbs` | +| `/tmp/en_all.json` + `/tmp/wm_clean.json` + `/tmp/all48.json` | 速卖通 | title/bullets/keywords;图片 URL 数组;仅用 keys | +| `shein_route.json` / `temu_route.json` / `alc_route.json` / `joom_route.json` | 各自平台 | 类目/店铺路由 | +| `ean_cursor.json` + `ean_temu_used.txt` | Temu | **EAN 游标,必须落盘防撞号** | + +**⚠ 两个 EAN 体系互不相通**:Temu 用 `69803093`+4 位流水自造;Walmart 用 `wm_input.json[oid].ean`。 +**⚠ `IN.weight`(克)在 SMT/SHEIN/Temu/aliChoice 4 个平台完全没被读取**;`IN.guess` 全平台 0 命中。 + + +--- + +## 5. 单位 / 币种 / 长度口径(最高频事故区) + +### 5.1 单位 ★★ +| 量 | 源口径 | 目标平台口径 | 换算 | +|---|---|---|---| +| 重量 | 1688:**`unitWeight`=kg / `pieceWeightScaleInfo[].weight`=g(两个字段并存)**;`unitWeight=0` 是"未填"不是零重;下游 `IN.weight` 多为硬编码占位 —— 详见 §1.5 | TikTok/Shopee **KG**;Walmart **lb**;Temu 重量+净重(g/kg) | `kg = g/1000`;`lb = kg×2.2046226`;`gToPound` 已有 | +| 尺寸 | 1688 `pieceWeightScaleInfo[].length/width/height` = **cm**(⚠ 9/17 样本为 0) | Walmart **inch**;Temu 尺寸图 cm/inch 双标 | `inch = cm/2.54` | +| 净重 | 需 ≤ 毛重 | Temu:**净重必须小于重量**(否则保存被拒) | 需估算或人工 | + +**已发生过的真实事故**:Shopee 把 `130(g)` 直接写成 `130 KG`;尺寸用重量推算得出 `169×101×34 cm`(★★ 需求 §3.5)。 + +### 5.2 币种 ★★ +| 平台 | 币种 | 换算线索 | +|---|---|---| +| Ozon | **CNY** | 价格带 0–1500₽ ≈ 0–113¥(≈13.27₽/¥) | +| TikTok | **MYR** | MYR ≈ CNY × 0.60 | +| Shopee | **CNY** | — | +| Walmart | USD | — | +| USD 通用 | — | `USD = CNY ÷ 6.68525`(店小秘 `siteAndUsCurrencyRate`) | +| KZT(哈萨克线) | KZT | `KZT_PER_CNY = 66.84` | + +### 5.3 长度上限 +| 平台 | 上限 | 证据强度 | +|---|---|---| +| Walmart | **100** | ★★ 需求 §3.9 实测(改写 9 条、超限 0、触发长度兜底 1 条) | +| Temu | **120** | ★★ 需求 §3.9 | +| 其他平台 | 脚本里有 `slice(0, 60/90/110/120/150/160/170)` | ❓ **多为日志截断,不等于平台上限**,接规则前须逐平台确认 | + +--- + +## 6. 词表与过滤规则 ★★(`lib/listing-rules.mjs`,已单测) + +| 常量 | 内容 | 用途 | +|---|---|---| +| `BRAND_DEFAULT` | `无品牌` | 全平台默认品牌 | +| `NARROW_WORDS` | boy/boys/girl/girls/children/child/kids/kid/school/teen/teenager/toy/toys/student/baby/babies/infant/toddler(25 词) | 窄义(儿童/学生)词 | +| `RISK_WORDS` | 中文侵权(侵权/仿/高仿/同款大牌/假货/A货/精仿/原单/山寨/盗版)+ 英文仿冒(replica/fake/knockoff/counterfeit/inspired by/same as/dupe/oem/authorized)+ 硬违禁(weapon/knife/gun/ammo/drug/cbd/medicine/cure/treatment/medical grade/fda approved/antibacterial/sterilize/virus/covid)+ 促销词(best price/hot sale/free shipping/buy now/discount/promotion) | 侵权/违禁 | +| `PLATFORM_RULES` | walmart `{narrow:true,risk:true}`;temu `{narrow:false,risk:true}`;smt/alichoice/tiktok/shopee/shein/joom/ozon `{narrow:false,risk:true}` | 各平台过滤集 | +| `SYNONYMS`(策略 B 同义替换) | `for kids/children/girls/boys` → `for Ages 3+`;`kids…` → `Ages 3+`;`toys` → `Party Favors`;`toy` → `Party Favor`;`students` → `Learners`;`school(s)` → `Everyday`;`teens/teenagers` → `Ages 12+`;`babies/baby/infant(s)/toddler(s)` → `Ages 0+` | 保搜索语义 | +| 约束 | 替换目标**自身不得命中**词表(`synonymSelfCheck()`);连续年龄段折叠成一个;**超长自动退回硬删再截断** | 防"换皮继续违规" | +| `filterTitle(title, platform, {mode, maxLen})` | `replace`(默认)/`strip` | 标题 | +| `filterDescription(html, platform)` | 只过滤文本节点,标签不动 | 描述 | +| `cmToInch / kgToPound / gToPound / dimsToInch / declaredValue` | 换算与货值一致 | §5 | +| `filterProductImages(urls, min=4)` | 按 `DETAIL_IMG_RE = /\/img\/ibank\/\d{4}\/\d{1,3}\/\d{1,3}\//`(拍摄日期目录 = **详情卡**)剔除;不足 4 张补回并标 `warn` | 图片卫生 | + +**实测效果**(48 条真实标题):Walmart 改写 9 条、最长 100;Temu 改写 9 条、最长 106;TikTok 0 条(不过滤窄义词)。 + +**⚠ 接线状态(grep 实证)**:**没有任何线上建品脚本 `import` 这个规则库**(工作副本 `platform-wmt/`、`platform-temu/`、`platform-tkt/` 三份是补丁版,尚未同步进线上 `~/<平台>建品/`)。后果: +- `filterProductImages()` 的 `keep` **没接回** `IN.imgs` 消费点 → 各平台仍上传**未过滤的原始图数组**(含详情卡/儿童 stock 图); +- `cmToInch/kgToPound/declaredValue/dimsToInch` 全部备而未用 → 于是出现「速卖通货值 0.50 vs 售价 1.99」(`declaredValue` 本可拦住)、「Walmart 的 `weight_lbs` 只能在输入文件里预先算好」。 + +--- + +## 7. 图片与视频规范 + +| 项 | 规范 | 证据 | +|---|---|---| +| 写法 | **全部外链**(alicdn 等),对象形如 `{url, imgUrl, name, width, height(, checked)}`,多数平台存**数组** | ★★ | +| 例外 | Walmart 必须走「网络图片」UI,落成 `\|` 分隔字符串;Temu `mainImage` 是 `\|` 分隔外链串且**能落库** | ★★ | +| 禁含 | **中文、促销字样、水印、联系方式**(平台会删/拒) | ★★ | +| 主图 vs 详情图 | 1688 `IN.imgs` **混装**;上传前过 `filterProductImages()`;实测 48 商品 279 图里 12 张是详情卡 | ★★ | +| 儿童/模特图 | 含儿童的 stock 图在 Walmart/Temu 属高风险,一并剔除;模特图经 rembg 后模特仍在,不能当白底图 | ★★ | +| 白底图 | FlairGS `POST /api/white-bg`,**800×800 / 3.6s**,rembg 路线,不依赖 Forge ✅ 可用 | ★★ | +| 场景图 | flux `POST /api/generate-scene`(768×1024 / 66–76s)技术可用但**构图不合格**;forge 引擎 HTTP 500/503 ❌ | ★★ | +| 去水印/去中文 | 依赖 Forge,当前 503 ❌ | ★★ | +| 尺寸图 | Temu 第 4 张必须是 **cm/inch 双标尺寸图** | ★★ | +| SHEIN 特有 | `squareImage`(方图)+ `mainImgData.{multipleSpuImgs, singleSpuImg}`,且页面有「新版/旧版图片」模式开关 | ★★ | +| 视频 | 速卖通(`video/videoUrl/installVideo`)、TikTok(`videoUrl/videoId/videoPostUrl`)均有槽位,**当前未填** | ★★ | + +--- + +## 8. 变种/变参体系(当前最弱的一环) + +| 平台 | 现状 | 目标 | +|---|---|---| +| 速卖通 | **无变参**(`smtProductSkuList` 未填) | 建变参(颜色/尺码)+ 变参图 | +| TikTok | 只填了变种属性值;**变种主题图未完成**(字段候选已列出) | 每个变种主题挂图 | +| Walmart | `hasVariant=false`(**变参被关掉**) | 开启变参 + 逐变参隔离图片 | +| Temu | SKU 行已建(含尺寸/重量/净重),变种属性靠 UI `.theme-value-add` | 已完成主体 | +| 通用字段 | `variantTheme, option1/2/3(+Value), variantList[], skuDataList[], variantImageIdMap, variationListStr` | — | + +**硬规则**:变参图**只能有当前变参的图,不能串图**(TikTok #4 / Walmart #7 / 速卖通 #8)。 + +--- + +## 9. 合规与平台特有硬性要求(逐条可验收) + +| # | 平台 | 要求 | 状态 | +|---|---|---|---| +| 1 | 速卖通 | 类目必须与店铺(4024039)授权类目对应,不得猜 | ❌ 待做(白名单) | +| 2 | 速卖通 | 标题用平台热词/长尾词(接 LLM) | ❌ 待做 | +| 3 | 速卖通 | 星号必填逐项填(产地/高关注化学品,类目有差异) | ⚠ 写死 id | +| 4 | 速卖通 | 主图无中文/促销字;一键生成白底(1:1)/场景(3:4)图 | ⚠ 白底可用、场景不合格 | +| 5 | 速卖通 | 产品视频 | ❌ 未填 | +| 6 | 速卖通 | 零售价与货值一致 | ⚠ 硬编码 1.99/0.50 | +| 7 | 速卖通 | PC/无线端描述带图 + 规范 HTML | ❌ 纯文字 | +| 8 | 速卖通 | 变参与变参图 | ❌ | +| 9 | 速卖通 | 来源 URL | ❌ | +| 10 | TikTok | 多国勾选 + 复制到其他店铺「全选」 | ✅ `siteIds` 已验证 | +| 11 | TikTok | 品牌=无品牌 | ✅ | +| 12 | TikTok | 描述含产品图 | ✅ | +| 13 | TikTok | 变种主题图 | ❌ | +| 14 | TikTok | 长/宽必填 | ✅ 回读 130/78/26 | +| 15 | TikTok | 货到付款 | ✅ `isCodOpen=1` | +| 16 | TikTok | 类目白名单 | ❌ | +| 17 | Walmart | 来源 1688 URL | ❌ | +| 18 | Walmart | 标题/描述过滤窄义词 | ✅ 已接 | +| 19 | Walmart | 标识符 = **ISBN** | ✅ 保存级验证 | +| 20 | Walmart | 品牌 = 无品牌 | ⚠ 批量里 store/checked 不一致,待编辑页确认 | +| 21 | Walmart | Country of Origin = China | ❌ | +| 22 | Walmart | 尺寸→英寸、重量→英镑 | ⚠ 重量已 lbs,尺寸未处理 | +| 23 | Walmart | 变参图隔离 | ❌(变参本身被关) | +| 24 | Temu | 标题过滤违禁/侵权 | ✅(本批无命中) | +| 25 | Temu | 图片无中文;第 4 张 cm/inch 尺寸图 | ❌ | +| 26 | Temu | 产品描述 | ✅ 已写 `describeInfoData` | +| 27 | Shopee | 剔除详情图(工厂照/证书/流程图/退货/FAQ) | ✅ `filterProductImages()` | +| 28 | Shopee | 重量克→千克 | ⚠ 已识别,待接线 | +| 29 | SHEIN | 图片落库 | ❌ **写 store 不进保存载荷** | + +--- + +## 10. 校验与回读(验收口径,不接受的写法) + +**教训(`建品质量需求.md` §3.11 原话)**:**回读校验必须断言"字段非空且与期望相等",只查"没有禁词"会自欺。** +第一版回读读的是 `hit.name`,而 Walmart 列表里标题字段叫 **`productName`** → "没找到字段 → 空串 → 判定无禁词"成了**假阳性**。 + +| 平台 | 回读接口 | 关键字段 | 判据 | +|---|---|---|---| +| Walmart | `POST /api/walmartProduct/pageList.json` | `productName / platformTitle / mainImage / productIdType` | 标题**精确相等** + 图片非空 | +| Temu | `POST /api/pddkjProduct/pageList.json`(模块名是 pddkjProduct) | `productName` | 精确相等 ✅ | +| SHEIN | `POST /api/sheinProduct/pageList.json` + `shopId=-1&dxmState=offline&productSearchType=1`(**没有** `dxmOfflineState`) | `mainImage` | 非空(用错参数 totalSize=0 会误判"没建成") | +| 通用 | `POST /api/<模块>Product/pageList.json` | `data.page.list` | — | + +**通用铁律** +1. **写 store ≠ 落库**:SHEIN 三个图位全写住仍 `mainImage:""`;Walmart `mainImage` 同类问题(一次保存全过程 22+ 条 `/api/` 请求**没有任何图片上传接口**,最终 POST 载荷仅 12 字节)→ 必须抓保存 POST 载荷判断"没进载荷"还是"要走上传递交"。 +2. **`idStr ≠ id`**:大整数在 JS 里丢精度,服务端操作(删除/详情)一律用 `idStr`。 +3. **"点保存没反应"先挂钩子**:校验报错被 `MYJ.message.error` 吞掉,且**层层递进**(修完 A 才显示 B)。 +4. **改 store 后校验仍失败**:UI 异步同步,**再点一次保存**可能就过。 +5. **类目不能猜**:必须与店铺授权类目对应,无匹配**跳过不硬选**。 +6. **跑之前先查重**:否则重试会产生重复(本会话踩过同一商品建 3 份)。 + +--- + +## 11. 我们自己的落库结构(`products.listings`)★★★ + +```js +{ + source: "dianxiaomi" | "miaoshou", // 同一集合双来源 + platform: "ozonProduct", // 接口模块名 + platformName: "Ozon", // 展示名 + state: "waitPublish" | "publishFail" | "online", + stateName: "待发布", + docKey: "184807701684308597", // idStr → productId → mergeId → 兜底哈希 + title, shopId, platformProductId, + price, currency, categoryId, categoryName, + mainImage, errMsg, + createTime, updateTime, + childCount: 3, // 合并组/变种子项数 + syncedAt, firstSeenAt, runId, gone, goneAt, + raw: { ...原始 item... } // ★ 平台字段全量在这 +} +``` +索引:`uniq_listing(source, platform, state, docKey)`、`by_state`、`by_synced`、`by_title`(text);同步账本 `products.sync_runs`。 + +**口径铁律**:**Ozon / Walmart 的「在线」返回的是合并组,不是子商品** —— 统计要用 `ΣchildCount`(Ozon 在线:组 2,593 → 子商品 20,415;Walmart:组 1,068 → 2,090)。分页行数不等长且会重复返回,脚本按 `docKey` 去重。 + +--- + +## 12. 妙手(miaoshou)侧 + +**平台 key → 名称**(`sync_msp_listings.py`:`ITEM_KEYS` **22 个**是接口实测认的键;`PLATFORM_NAMES` **39 个**另含授权页专用键 —— `*Choice/*Gs/*Scs/*Fc/*Local` 这类**item 接口不认、会返回 HTML**): +`pddkj`Temu全托管 · `pddkjChoice`Temu半托管 · `pddkjLocal`Temu本土 · `shopee` · `shopeeScs`Shopee全托管 · `shopeeSwarm`Shopee轻出海 · `tiktok` · `tiktokGs`TikTok全托管 · `lazada` · `lazadaChoice` · `ozon` · `yandex` · `wildberries` · `aliexpress` · `aliexpressChoice`速卖通半托管 · `aliexpressFc`速卖通全托管 · `aliexpressLocal`速卖通本土POP · `aliexpressOverseas`速卖通海外托管 · `amazon` · `coupang` · `alibaba` · `wish` · `shopify` · `daraz` · `joom` · `allegro` · `qoo10` · `shoplazza` · `jumia` · `walmart` · `shopline` · `shein` · `sheinChoice`SHEIN半托管 · `emag` · `noon` · `miravia` · `joybuy` · `mercado`Mercado Libre + +**妙手的状态机**:只有 `waitPublish`(采集箱未发布)/ `online`(发布成功)两态。 + +#### 12.1 接口信封(实测确认)★★★ +| 接口 | 关键参数 | 响应键 | +|---|---|---| +| `POST /api/auth/shop/getShopList` | `pageNo,pageSize,platform,includeShopeeGlobal=0,excludeShopeeCnscShop=0`(**缺后两个报「页码数据有误」**) | `shopList[]`(取 `shopId`/`id`) | +| `POST /api/platform/<key>/item/item/searchItemList`(**在线**) | `titleType=multi` + **必须带 `shopIds[i]`**(否则「没有符合条件的记录」) | `{result,itemList,total}` | +| `POST /api/platform/<key>/move/collect_box/searchCollectBoxDetail`(**待发布**) | `claimPublishShopStatus=published&titleType=multi&remarkType=multi&status=notPublished` | `{result,detailList,total}` | +| `POST …/collect_box/getTabCountStatMap` | — | `{count,notPublishedCount,publishedCount,timingPublishCount,aiOptimize*}` | +| 错误 | — | `{result, reason}`(`reason` 即错误文案) | + +边界:**yandex 回 HTTP 200 + 空体** = 无此功能,脚本按 `_empty` 处理,不报整轮错误。 + +#### 12.2 入库字段映射(`source='miaoshou'`)★★ +| 字段 | 取值候选(按序) | 备注 | +|---|---|---| +| `docKey` | `collectBoxDetailId`→`itemId`→`id`→`sourceItemId`,兜底 `'h'+hash(item)` | 幂等唯一键 | +| `title` | `title`→`itemName`→`name`→`productTitle`→`itemNum` | | +| `shopId` | `shopId` / `authShopId` | | +| `platformProductId` | `platformItemId` | | +| `price` | **`salePrice`(非空优先)** → `price` → `minSkuPrice` | ⚠ **与店小秘顺序相反**(店小秘 `price`→`salePrice`) | +| `currency` | `currency` / `sourceCurrency` | | +| `categoryId` | `cid` / `categoryId` | | +| `categoryName` | **硬编码 `None`** | 妙手侧未取 | +| `mainImage` | `picUrl` / `listThumbnail` / `thumbnail` | | +| `errMsg` | `reason` | | +| `createTime`/`updateTime` | `gmtCreate`/`ts`;`gmtModified` | | +| `childCount` | **硬编码 `None`** | 妙手无合并组映射 | +| `raw` | 原始 item 全量 | 保底 | +> ⚠ 上表 API 侧键名来自脚本 `first_of` 候选列表("脚本认为可能存在");**能确证有值的只有信封的 `total/itemList/detailList`**。 + +#### 12.3 妙手平台与计数(`msp-platforms.json` / `msp-collectbox.json`)★★★ +| 平台键 | 店铺 | 采集箱 count | 待发布 | 已发布 | 在线 | +|---|---:|---:|---:|---:|---:| +| **pddkj**(Temu全托管) | **14** | 46 | **45** | 1 | **55,462** | +| **tiktok** | 0 | 4,341 | **2,744** | 1,597 | — | +| **shopee** | 0 | 170 | **37** | 133 | — | +| **shein** | 0 | 44 | **44** | 0 | — | +| **ozon** | 0 | 1,555 | 0 | 1,555 | —(无店铺,在线同步不了) | +| 其余 16 键 | 0 | 0 | 0 | 0 | — | + +- 有「待发布」数据:`pddkj 45 + shopee 37 + tiktok 2744 + shein 44 = **2870**` +- 有「在线」数据:**仅 pddkj = 55,462** +- ⚠ **口径冲突**:pddkj 采集箱「已发布」只有 1,而在线 55,462;ozon 采集箱「已发布」1,555 却无店铺 → **采集箱「已发布」≠ 产品管理「在线」,勿混用**。 +- ⚠ `msp-platforms/collectbox/shops.json` **三个 JSON 是孤儿快照**(`sync_msp_listings.py` 不读它们,生成脚本未找到)。`msp-shops.json` 是空 `{}`。 + +#### 12.4 妙手刊登/导入参数(有来源)★★ +| 参数 | 内容 | 来源 | +|---|---|---| +| **导入「链接采集」8 列 `.xls`** | `产品主编号`(1688 id,**必须**)、`链接地址(必填)`、`产品标题`、`货币类型`(**必须**,空报「不允许此货币类型」)、`SKU售价`(**必须 ≥0.01**)、`SKU库存`(**必须 ≥0**)、`价格(RMB)`、`促销价(RMB)` | `~/miaoshou/RECIPE.md`(实测解析 **47/0/47**) | +| 页面下载的官方模板 | 仅 **4 列**(`链接地址/产品标题/价格(RMB)/促销价(RMB)`),**缺 `产品主编号` → 照它填必失败** | 同上 | +| ⚠ 文档矛盾 | `archived/miaoshou-batch-import`(2026-04) 断言「严格 5 列,**绝不能加** `产品主编号`」;`RECIPE.md`(2026-09-21) 实测「**必须加**」 → **以 09-21 的 8 列为准**(服务端模板已演进) | — | +| 采集箱编辑弹窗 Tab | `基本信息 / 产品属性 / 销售属性 / 产品图片 / 产品视频 / 认证说明 / 物流信息 / 货源链接`(容器 `.collect-box-editor`) | `archived/miaoshou-collect-box`(369 行) | +| 标题 / 产品主编号 / 简易描述 / 详细描述 | 标题 `input[type=text]`;主编号 `input[1]`(placeholder「不填将自动生成」);**简易描述 `textarea[0]`** → 用于 **Shopee/Wish/Joom/Mercado Libre/Ozon/Walmart**;**详细描述 `iframe[0]`(富文本)** → 用于 **Lazada/速卖通/TikTok/Coupang/eBay/Allegro** | 同上 | +| 促销价(RMB) | 表头注明「**仅可用于采集到 Lazada**」 | `RECIPE.md` | +| 采集箱筛选/动作 | 筛选:`关联货源/产品标题/货源ID/货源价格`;动作:`任务记录/认领到/平台认领配置/批量编辑/分组/删除/创建产品/导入产品/列表设置` | 同上 | +| 导入任务列表 | `文件名称/导入时间/解析状态/成功条数/失败条数/操作`(文件保留 90 天) | 同上 | +| Ozon 刊登必填 | 分类、标题(俄语)、描述、价格(¥×12~15×1.5~2)、库存、图片;店铺需 Ozon `Client ID + API Key` | `1688-to-ozon-listing-workflow` | +| Vue 状态同步 | 写值后必须 dispatch `input`/`change`/`blur`,否则点保存**静默丢弃** | `archived/miaoshou-collect-box` | +| 链接采集 URL 格式 | `URL` / `URL$$title` / `URL\|\|title` | `miaoshou-erp/SKILL.md` | + +#### 12.5 妙手 vs 店小秘 关键差异 ★★ +| 维度 | 妙手 | 店小秘 | +|---|---|---| +| 平台键 | 裸键 `pddkj`,**按平台分路径** `/api/platform/<key>/…` | module 名 `ozonProduct`/`smtProduct`,统一 `POST /api/<module>/pageList.json` | +| 状态机 | **2 态** | **3 态**(多 `publishFail`) | +| 在线前置 | **必须 `shopIds[i]`** | 无需 | +| 发布失败 | 无对应状态,仅 `errMsg ← reason` | 独立状态 + `errMsg/auditFailureReason` | +| ID | `collectBoxDetailId→itemId→…`,**无 idStr 概念** | `idStr→productId→mergeId`,**idStr 优先** | +| 价格键序 | `salePrice→price→minSkuPrice` | `price→salePrice`(**相反**) | +| 子商品 | **`childCount=None`** | `products/productList` 或 `productNum/count`(合并组) | +| 分页 | `PAGE_SIZE=500`(111 页 × 500 = 55,462 ✓) | `PAGE_SIZE=200`(**传 500 只回 100**) | +| 图片 | **无外链/上传字段证据**;靠「链接采集」由妙手服务端抓源页 | 建品表单**全用外链**;Walmart 例外走「网络图片」UI | +| 发布 | 未打通(子账号无发布权限) | 「保存并移入待发布」已跑通 | +| Joom | 纳入 | **默认排除 `joomProduct`** | + +#### 12.6 妙手侧"无证据"清单(不编造)❓ +1. **妙手各平台刊登 API 字段**(重量/尺寸/EAN/品牌/变种/类目差异)——**零证据**,无文档也无代码。 +2. 是否有 `publishFail` / 定时发布状态(只有 `timingPublishCount` 计数键)。 +3. `msp-shops.json` 为空;店铺只在运行时 `getShopList` 现取。 +4. 妙手侧 `title/price/categoryId/mainImage` 候选键**哪些真命中**(无 raw 样本落盘)。 +5. 妙手图片是外链还是上传——**未验证**。 +6. 「采集并自动发布」是否真能发布——自述"待实测",权限口径有冲突。 + + +**妙手文档字段(raw,以平台为单位)**:公共骨架高度一致,含 +`collectBoxDetailId, collectBoxGroupId/Name, commonCollectBoxDetailId, platform, platformItemId, source/sourceItemId/sourceItemUrl/sourceSite/sourceShopName, sourceList[], title, thumbnail/listThumbnail, price, stock, minWeight/maxWeight, minSkuPrice/maxSkuPrice, sitePriceMap, siteAndCatMap, siteAndCidMap, shopIds, pubShopList, timingShopList, importTemplateType, copyType, dataPath, infringementDetectResult, taskProcessStatusList, status, gmtCreate/gmtModified` +平台差异:TikTok 多 `packageL/W/H, weight, siteWeightMap, isSupportReplicateProduct, *IncludeVat` 等;Shopee 多 `promotion, hasSavePrice/hasSaveSite/hasTranslate, maxOriginPrice`;Temu 多 `collectBoxDetailShopList[]{brandId, breadcrumb, cid, currency, sizeTemplateId…}`。 + +**与店小秘的差异**:妙手用 `collectBox`(采集箱)作为待发布容器,字段名以 `collectBox*` 前缀;店小秘用 `dxmState/dxmOfflineState` 状态位。两者都保留 `sourceItemUrl`(1688 来源)。 + +--- + +## 13. 字段可得性矩阵(能不能自动拿到) + +| 字段 | L1 源 | 自动可得 | 需人工/生成 | 备注 | +|---|---|---|---|---| +| 标题/卖点/关键词 | ✅ | ✅ | | 需过滤 + 可 AI 优化 | +| 价格/成本 | ✅ | ✅ | | 定价公式已有 | +| 重量 | ⚠ 口径不一 | ⚠ | ✅ 校核 | 单位事故高发 | +| 包装尺寸 | ⚠ 常缺 | ⚠ | ✅ | 禁止用重量推算 | +| 主图 | ✅ | ✅ | | 必须过滤详情图/中文 | +| 白底图 | — | ✅ | | FlairGS 可用 | +| 场景图 | — | ❌ | ✅ | flux 构图不合格 | +| 视频 | ❌ | ❌ | ✅ | 需生成或人工 | +| 变种定义 | ⚠ | ⚠ | ✅ | 1688 规格 → 变种映射 | +| 变种图 | ⚠ | ⚠ | ✅ | 串图风险 | +| 品牌 | ❌ | — | 固定 `无品牌` | | +| EAN/UPC/ISBN | ❌ | ✅ | | 自建台账(S03 落账) | +| 原产国/产地 | ⚠ 供应商 | ⚠ | ✅ | 默认 China | +| HS 编码 | ❌ | ⚠ | ✅ | 类目映射 | +| 高关注化学品 | ❌ | — | 固定 `none` | | +| 说明书文件 | ❌ | ❌ | ✅ | 速卖通部分类目强制 | +| 类目 | ⚠ 猜 | ❌ | ✅ | 必须店铺授权白名单 | +| 尺码表 | ⚠ | ⚠ | ✅ | SHEIN/Shopee 需要 | + +--- + +## 14. 待确认 / 缺口(按优先级) + +**P0(正在流血)** +1. **妙手 cookie 已过期**,22 平台全 `授权已经过期`,而监控报 OK(见 §0)→ 需重登 + 修判据。 +2. **SHEIN / Walmart 的 `mainImage` 不落库**(写 store 不进保存载荷)→ 需抓保存 POST 载荷定位。 +3. **规则库未接线**:`filterProductImages / cmToInch / kgToPound / declaredValue / dimsToInch` 一个都没被线上脚本 import(见 §6)。 + +**P1(字段口径)** +4. **重量源口径未统一**:`unitWeight`(kg) vs `pieceWeightScaleInfo.weight`(g),且 `unitWeight=0` 要当缺失(见 §1.5)。 +5. **`IN.weight`(克) 在 4 个平台完全没被读取**,尺寸在 Shopee/TikTok 仍是重量推导、其余平台硬编码(见 §4.4/§4.5)。 +6. **两个 EAN 体系互不相通**(Temu 自造 vs Walmart 输入包),且都需回 S03 落账。 +7. **各平台标题长度上限**:只有 Walmart(100)/Temu(120) 实测;其余脚本里的 `slice` 不能当上限。 + +**P2(能力缺口)** +8. **Ozon 无建品脚本**(只有改价)→ 要 Ozon 字段清单必须先写脚本。 +9. **Temu 第 4 张尺寸图**生成方式;**场景图路线**(等 Forge 还是 txt2img+PIL 合成)。 +10. **变参体系**:1688 规格 → 平台变种主题的对齐规则(含变种图隔离)。 +11. **妙手各平台刊登字段**:零证据,需要一篇自己的实测(妙手侧没有对应文档)。 + +**P3(决策)** +12. **存量 47×8 条是否补字段**(走编辑页)还是作废重建。 +13. **1688 抓取路线裁决**:BDPM curl(实测可行)vs Desktop CDP(旧技能主张)。 +14. 产品库库名冲突:`premiumproducts.products` vs `productpool1.products`。 +15. 失效引用清理:`1688-cross-border-sourcing` 技能引用的 `~/.hermes/scripts/1688_scrape_cdp.py` 与 `references/*` 在本机不存在。