店小秘多平台铺货配方:7 平台建品脚本 + 静默拦截诊断法 + 项目状态
- TikTok/Shopee/速卖通/Walmart 各 46-47 条已在待发布 - Ozon 47 条已建、改价 40/47 - SHEIN 配方跑通第一条;Temu 差「预览图」一步 - 核心产出:MYJ.message.error 钩子诊断法(解开了三个平台的保存静默拦截) - 含下一轮提示词 NEXT-ROUND-PROMPT.md
This commit is contained in:
commit
f5720ad613
94 files changed
+21561
No files matched your search
@@ -0,0 +1,182 @@
|
||||
{
|
||||
"548459586741": {
|
||||
"ok": false,
|
||||
"cat": ""
|
||||
},
|
||||
"764423265986": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Peralatan Dapur(厨房用品)/Perkakas & Alat Dapur(厨房器具)/Termometer Dapur(厨房温度计)"
|
||||
},
|
||||
"685456757807": {
|
||||
"ok": false,
|
||||
"cat": ""
|
||||
},
|
||||
"735147938123": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Cekak Rambut(发带发箍)"
|
||||
},
|
||||
"610164857063": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Cekak Rambut(发带发箍)"
|
||||
},
|
||||
"676236596821": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Klip Rambut & Pin Rambut(发夹发簪)"
|
||||
},
|
||||
"708420302844": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kemas & Aksesori Kostum(平价饰品)/Rantai Kunci(钥匙扣)"
|
||||
},
|
||||
"866537106657": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Bayi & Bersalin(母婴用品)/Penjagaan & Kesihatan Bayi(婴儿护理与健康)/Lampin(尿布)/Aksesori Lampin Kain(布尿布配件)/P"
|
||||
},
|
||||
"547183997437": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/14]:Aksesori & Hasil Barang Kemas(珠宝与衍生品)/Ambar(琥珀)/Rantai & Loket Ambar(琥珀项链&吊坠) | 尝试: 项链→picked[0/14]:Aksesori & Hasil Barang Kemas(珠宝"
|
||||
},
|
||||
"657617635303": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/3]:Bekalan Rumah(居家日用)/Pengatur Rumah(家居收纳)/Kotak & Tong Penyimpanan(收纳盒) | 尝试: 收纳盒→picked[0/3]:Bekalan Rumah(居家日用)/Pengatur Ruma"
|
||||
},
|
||||
"641673262387": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Bagasi & Beg(箱包)/Beg Bagasi & Perjalanan(旅行箱包)/Pengaturan Perjalanan(旅行收纳袋) | 尝试: 首饰袋→no-result / 首饰盒→no-result / 收纳袋→picked[0/1]:Bagasi & Beg(箱包)/Beg Bagasi & Per"
|
||||
},
|
||||
"953869908708": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/4]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Label, Pembahagi Indeks & | 尝试: 窗贴→no-result / 贴纸→picked[0/4]:Komputer & Peralatan Pejabat(电脑办公"
|
||||
},
|
||||
"703822717997": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/19]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Alatan Penulisan & Pembet | 尝试: 笔夹→no-result / 笔夹→no-result / 文具→picked[0/19]:Komputer & Peralatan Pejabat(电脑办"
|
||||
},
|
||||
"863524134410": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/4]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Label, Pembahagi Indeks & | 尝试: 贴纸→picked[0/4]:Komputer & Peralatan Pejabat(电脑办公"
|
||||
},
|
||||
"694637537727": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Bagasi & Beg(箱包)/Beg Fungsian(功能箱包)/Beg Pendingin(保温袋) | 尝试: 保温袋→picked[0/1]:Bagasi & Beg(箱包)/Beg Fungsian(功能箱"
|
||||
},
|
||||
"623011262210": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/4]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Label, Pembahagi Indeks & | 尝试: 窗贴→no-result / 贴纸→picked[0/4]:Komputer & Peralatan Pejabat(电脑办公"
|
||||
},
|
||||
"836512561982": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/2]:Kecantikan & Penjagaan Diri(美妆个护)/Mekap(美妆)/Alatan Solekan(化妆工具)/Beg dan Bekas Solek(化妆包及化妆盒) | 尝试: 化妆包→picked[0/2]:Kecantikan & Penjagaan Diri(美妆个护)"
|
||||
},
|
||||
"714492799386": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/2]:Kecantikan & Penjagaan Diri(美妆个护)/Mekap(美妆)/Alatan Solekan(化妆工具)/Beg dan Bekas Solek(化妆包及化妆盒) | 尝试: 化妆包→picked[0/2]:Kecantikan & Penjagaan Diri(美妆个护)"
|
||||
},
|
||||
"591994902720": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/19]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Alatan Penulisan & Pembet | 尝试: 笔袋→no-result / 笔袋→no-result / 文具→picked[0/19]:Komputer & Peralatan Pejabat(电脑办"
|
||||
},
|
||||
"853414558425": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Telefon & Elektronik(手机与数码)/Aksesori Telefon(手机配件)/Tali & Hiasan Telefon(手机挂绳与挂件) | 尝试: 手机挂绳→picked[0/1]:Telefon & Elektronik(手机与数码)/Akses"
|
||||
},
|
||||
"997450831819": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/4]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Label, Pembahagi Indeks & | 尝试: 贴纸→picked[0/4]:Komputer & Peralatan Pejabat(电脑办公"
|
||||
},
|
||||
"639409307567": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/4]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Label, Pembahagi Indeks & | 尝试: 墙贴→no-result / 贴纸→picked[0/4]:Komputer & Peralatan Pejabat(电脑办公"
|
||||
},
|
||||
"902440558099": {
|
||||
"ok": true,
|
||||
"cat": "picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fesyen Bayi(婴儿时尚配件)/Aksesori Rambut Bayi(婴儿发饰) | 尝试: 发圈→no-result / 发饰→picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fe"
|
||||
},
|
||||
"823838532886": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/2]:Bagasi & Beg(箱包)/Beg Lelaki(男包)/Dompet(钱包) | 尝试: 卡套→no-result / 卡包→no-result / 卡套→no-result / 钱包→picked[0/2]:Bagasi & Beg(箱包)/Beg Lelaki(男包)/D"
|
||||
},
|
||||
"698782391248": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/4]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Label, Pembahagi Indeks & | 尝试: 贴纸→picked[0/4]:Komputer & Peralatan Pejabat(电脑办公"
|
||||
},
|
||||
"707826905566": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/2]:Bagasi & Beg(箱包)/Beg Lelaki(男包)/Dompet(钱包) | 尝试: 卡包→no-result / 卡包→no-result / 卡套→no-result / 钱包→picked[0/2]:Bagasi & Beg(箱包)/Beg Lelaki(男包)/D"
|
||||
},
|
||||
"1027332215847": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/3]:Bekalan Rumah(居家日用)/Pengatur Rumah(家居收纳)/Kotak & Tong Penyimpanan(收纳盒) | 尝试: 收纳盒→picked[0/3]:Bekalan Rumah(居家日用)/Pengatur Ruma"
|
||||
},
|
||||
"682195499823": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/19]:Komputer & Peralatan Pejabat(电脑办公)/Alat Tulis & Bekalan Pejabat(办公文具用品)/Alatan Penulisan & Pembet | 尝试: 笔袋→no-result / 笔袋→no-result / 文具→picked[0/19]:Komputer & Peralatan Pejabat(电脑办"
|
||||
},
|
||||
"823560564174": {
|
||||
"ok": true,
|
||||
"cat": "picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fesyen Bayi(婴儿时尚配件)/Aksesori Rambut Bayi(婴儿发饰) | 尝试: 发圈→no-result / 发饰→picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fe"
|
||||
},
|
||||
"739147684759": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Bayi & Bersalin(母婴用品)/Penjagaan & Kesihatan Bayi(婴儿护理与健康)/Lampin(尿布)/Aksesori Lampin Kain(布尿布配件)/P | 尝试: 纽扣→picked[0/1]:Bayi & Bersalin(母婴用品)/Penjagaan &"
|
||||
},
|
||||
"621300323670": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/78]:Komputer & Peralatan Pejabat(电脑办公)/Peralatan Pejabat(办公设备)/Alat Ganti Peralatan Pejabat(办公设备零部件) | 尝试: 胶带座→no-result / 胶带座→no-result / 办公→picked[0/78]:Komputer & Peralatan Pejabat(电脑办"
|
||||
},
|
||||
"896469995553": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kemas & Aksesori Kostum(平价饰品)/Rantai Kunci(钥匙扣) | 尝试: 钥匙扣→picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kema"
|
||||
},
|
||||
"944470567338": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Klip Rambut & Pin Rambut(发夹发簪) | 尝试: 发夹→picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Ra"
|
||||
},
|
||||
"787261097583": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Klip Rambut & Pin Rambut(发夹发簪) | 尝试: 发夹→picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Ra"
|
||||
},
|
||||
"833753630925": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Cekak Rambut(发带发箍) | 尝试: 发箍→picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Ra"
|
||||
},
|
||||
"719391062058": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/3]:Bekalan Rumah(居家日用)/Pengatur Rumah(家居收纳)/Kotak & Tong Penyimpanan(收纳盒) | 尝试: 收纳盒→picked[0/3]:Bekalan Rumah(居家日用)/Pengatur Ruma"
|
||||
},
|
||||
"857781294719": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Klip Rambut & Pin Rambut(发夹发簪) | 尝试: 发夹→picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Ra"
|
||||
},
|
||||
"863384503032": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Klip Rambut & Pin Rambut(发夹发簪) | 尝试: 发夹→picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Ra"
|
||||
},
|
||||
"774494945453": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kemas & Aksesori Kostum(平价饰品)/Rantai Kunci(钥匙扣) | 尝试: 钥匙扣→picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kema"
|
||||
},
|
||||
"750271307455": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kemas & Aksesori Kostum(平价饰品)/Rantai Kunci(钥匙扣) | 尝试: 钥匙扣→picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kema"
|
||||
},
|
||||
"726442972676": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Klip Rambut & Pin Rambut(发夹发簪) | 尝试: 发夹→picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Ra"
|
||||
},
|
||||
"775057912118": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kemas & Aksesori Kostum(平价饰品)/Rantai Kunci(钥匙扣) | 尝试: 钥匙扣→picked[0/1]:Aksesori Fesyen(时尚配件)/Barang Kema"
|
||||
},
|
||||
"893592264148": {
|
||||
"ok": true,
|
||||
"cat": "picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Rambut(发饰)/Klip Rambut & Pin Rambut(发夹发簪) | 尝试: 发夹→picked[0/1]:Aksesori Fesyen(时尚配件)/Aksesori Ra"
|
||||
},
|
||||
"607330049419": {
|
||||
"ok": true,
|
||||
"cat": "picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fesyen Bayi(婴儿时尚配件)/Aksesori Rambut Bayi(婴儿发饰) | 尝试: 发圈→no-result / 发饰→picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fe"
|
||||
},
|
||||
"854003999648": {
|
||||
"ok": true,
|
||||
"cat": "picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fesyen Bayi(婴儿时尚配件)/Aksesori Rambut Bayi(婴儿发饰) | 尝试: 发圈→no-result / 发饰→picked[1/6]:Bayi & Bersalin(母婴用品)/Aksesori Fe"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1 @@
|
||||
{"n":184,"items":[{"id":"184807703510005077","name":"Pure Natural Cotton Yarn for Baby Knitting - Soft 16-Ply","shop":5880976,"cat":951816,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510004697","name":"6.5cm Colorful Plastic Party Whistles for Kids, Blow Out Whistle Toys for Birthday Sports Games","shop":5880976,"cat":604390,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510004269","name":"High Elastic Wide Hair Ties Set of 5, Soft No-Break Hair Bands","shop":5880976,"cat":962696,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510004059","name":"50 Pcs Elastic Thin Hair Ties for Women Girls Daily Use","shop":5880976,"cat":962696,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510003789","name":"Cute Plaid Hair Clips & Bands for Kids, Bright Yellow Children's Hair Accessories","shop":5880976,"cat":908552,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510003519","name":"Stainless Steel Keychain with English Letter, Polished Metal Key Holder for Car Bag","shop":5880976,"cat":907656,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510003301","name":"Cute Cartoon Animal Mini Hair Clips for Bangs and Small Strands","shop":5880976,"cat":908552,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510003143","name":"Romantic Heart Keychain for Couples Silver Plated Valentine Gift","shop":5880976,"cat":907656,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510002979","name":"Stainless Steel Cat Keychain with Fish Charm Cute Bag Ornament","shop":5880976,"cat":907656,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510002811","name":"Elegant Red Rose Crab Hair Clip for Women Stylish Accessory","shop":5880976,"cat":908552,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510002613","name":"Cute Bunny Ear Hair Clips for Kids with Ribbon Bow, 2 Pcs","shop":5880976,"cat":908552,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510002419","name":"Clear Cosmetic Organizer with 6 Drawers for Desk Storage","shop":5880976,"cat":600621,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510002205","name":"Wide Plaid Fabric Headband for Women - Comfortable Hair Accessory","shop":5880976,"cat":605271,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510001565","name":"Transparent Crab Hair Clips with Hearts, Clear Acrylic Set","shop":5880976,"cat":908552,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510000821","name":"Korean Style Plaid Triangle Hair Clip with Decorative Button","shop":5880976,"cat":908552,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510000487","name":"Angel Wings & Stars Keychain Y2K Retro Bag Charm Cute Accessory","shop":5880976,"cat":907656,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703510000053","name":"Round Transparent Desktop Tape Dispenser with Smooth Cutter","shop":5880976,"cat":987656,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509999761","name":"Metallic Rectangular Coat Buttons with Leather Cover for Jackets","shop":5880976,"cat":1944336,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509999371","name":"Cute Heart Hair Ties Set, Soft Elastic Bands for Buns & Ponytails, Colorful Hair Accessories","shop":5880976,"cat":962696,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509998877","name":"96-Cell Brush Organizer Case for Watercolor & Gouache","shop":5880976,"cat":603002,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509998697","name":"Silver Matte Tin Photo Box with Clear Window for Cards","shop":5880976,"cat":600621,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509998203","name":"Ultra-Slim Card Holder Wallet for Men Women, Compact Cash & Card Pouch","shop":5880976,"cat":601430,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509997509","name":"Boho Style White PVC Laptop Stickers 10cm Round Decal","shop":5880976,"cat":988296,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509997369","name":"Cute Cartoon Cat Key Card Holder for Metro Office & Bag","shop":5880976,"cat":601430,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509996723","name":"Large Beige Fabric Hair Tie with Pearl for Buns and Low Ponytails","shop":5880976,"cat":962696,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509996281","name":"3D Glowing Butterfly Wall Stickers, Magnetic Light Up Decals","shop":5880976,"cat":988296,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509995631","name":"Matte PET Emoji Stickers for Goodnotes & Scrapbooking, 10 Sheets Waterproof","shop":5880976,"cat":988296,"catPath":"","img":1,"vars":0,"price":"","weight":""},{"id":"184807703509995245","Line truncated
|
||||
@@ -0,0 +1,211 @@
|
||||
import { newTarget, CDP, SAN } from '/tmp/cdp3.mjs';
|
||||
import fs from 'fs';
|
||||
|
||||
/* ── TikTok (AutoMavenShop_MY) 建品配方 ──
|
||||
node tkbatch.mjs <oid> [catKeyword] [variantValue]
|
||||
流程:选店铺 → 分类弹窗 → 标题/卖点/关键词/描述 → 变种属性 → SKU价+库存
|
||||
→ 重量/尺寸 → 仓库 → 图片(外链) → 来源URL → 保存 → 回读 */
|
||||
|
||||
const OID = process.argv[2];
|
||||
const CAT_KW = process.argv[3] || '';
|
||||
const VAR_VAL = process.argv[4] || 'Default';
|
||||
if (!OID) { console.log('用法: node tkbatch.mjs <oid> [catKeyword] [variantValue]'); process.exit(1); }
|
||||
|
||||
const IN = JSON.parse(fs.readFileSync('/tmp/tk_input.json', 'utf8'))[OID];
|
||||
if (!IN) { console.log('无输入数据', OID); process.exit(1); }
|
||||
|
||||
const wait = ms => new Promise(z => setTimeout(z, ms));
|
||||
const log = (...a) => console.log(' ', ...a);
|
||||
const DIMS = (() => { const W = Math.max(100, Math.round(IN.weight * 1.3));
|
||||
return { L: Math.max(60, Math.min(400, W)), Wi: Math.max(40, Math.min(300, Math.round(W * 0.6))), H: Math.max(10, Math.min(200, Math.round(W * 0.2))) }; })();
|
||||
|
||||
// 0. 清理编辑页
|
||||
const tl = await (await fetch('http://127.0.0.1:9223/json/list')).json();
|
||||
let k = 0;
|
||||
for (const t of tl.filter(x => x.type === 'page' && /tiktok/i.test(x.url))) { await fetch(`http://127.0.0.1:9223/json/close/${t.id}`).catch(() => {}); k++; }
|
||||
if (k) { log(`清理 tiktok 页 ${k} 个`); await wait(1200); }
|
||||
|
||||
const t = await newTarget('about:blank');
|
||||
const c = await CDP.connect(t.webSocketDebuggerUrl);
|
||||
await c.send('Page.enable'); await c.send('Runtime.enable');
|
||||
await c.send('Page.navigate', { url: 'https://www.dianxiaomi.com/web/tiktokProduct/add' });
|
||||
await wait(20000);
|
||||
|
||||
const cur = async () => String(await c.evalJS(`(()=>{const s=[...document.querySelectorAll('.ant-select')].filter(e=>e.offsetParent!==null)[0];
|
||||
return s?((s.querySelector('.ant-select-selection-item')||{}).innerText||''):'';})()`));
|
||||
|
||||
// 1. 选店铺 AutoMavenShop_MY
|
||||
async function pickShop() {
|
||||
for (let attempt = 0; attempt < 3; attempt++) {
|
||||
const pos = JSON.parse(String(await c.evalJS(`(()=>{const s=[...document.querySelectorAll('.ant-select')].filter(e=>e.offsetParent!==null)[0];
|
||||
if(!s)return'[]'; s.scrollIntoView({block:'center'}); const r=s.getBoundingClientRect();
|
||||
return JSON.stringify([Math.round(r.x+r.width/2),Math.round(r.y+r.height/2)]);})()`)));
|
||||
if (!pos.length) return 'no-select';
|
||||
for (const type of ['mousePressed', 'mouseReleased']) await c.send('Input.dispatchMouseEvent', { type, x: pos[0], y: pos[1], button: 'left', clickCount: 1 });
|
||||
await wait(1800);
|
||||
await c.evalJS(`(()=>{const inp=document.querySelector('.ant-select-selection-search-input')||document.querySelector('.ant-select input');
|
||||
if(!inp)return 0; inp.focus();
|
||||
Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set.call(inp,'AutoMaven');
|
||||
inp.dispatchEvent(new Event('input',{bubbles:true})); return 1;})()`);
|
||||
await wait(2200);
|
||||
const r = await c.evalJS(`(()=>{const dd=[...document.querySelectorAll('.ant-select-dropdown')].filter(e=>e.offsetParent!==null);
|
||||
if(!dd.length)return'no-dd'; const d=dd[dd.length-1];
|
||||
const hit=[...d.querySelectorAll('.ant-select-item-option')].find(o=>/AutoMavenShop_MY/i.test(o.innerText||''));
|
||||
if(!hit)return'no-hit';
|
||||
for(const ev of ['mousedown','mouseup','click']) hit.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window}));
|
||||
return 'picked';})()`);
|
||||
await wait(6000);
|
||||
const s = await cur();
|
||||
if (/AutoMavenShop_MY/i.test(s)) return 'ok:' + s;
|
||||
log(' 店铺重试', attempt + 1, r, JSON.stringify(s));
|
||||
}
|
||||
return 'fail';
|
||||
}
|
||||
|
||||
// 2. 分类
|
||||
async function pickCategory(kw) {
|
||||
await c.evalJS(`(()=>{document.querySelectorAll('.ant-select-dropdown').forEach(d=>{if(d.offsetParent!==null)d.style.display='none';});
|
||||
document.body.dispatchEvent(new MouseEvent('mousedown',{bubbles:true})); document.body.click(); return 1;})()`);
|
||||
await wait(1000);
|
||||
const open = await c.evalJS(`(()=>{const b=[...document.querySelectorAll('button,a,span')].filter(e=>e.offsetParent!==null&&/^\\s*选择分类\\s*$/.test(e.innerText||''));
|
||||
if(!b.length)return'nf'; for(const ev of ['mousedown','mouseup','click']) b[0].dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return 'ok';})()`);
|
||||
if (open === 'nf') return 'no-btn';
|
||||
await wait(3500);
|
||||
const r = await c.evalJS(`(()=>{const m=[...document.querySelectorAll('.ant-modal')].filter(e=>e.offsetParent!==null).pop();
|
||||
if(!m)return'no-modal'; const inp=m.querySelector('input[placeholder="搜索分类名称"]'); if(!inp)return'no-input';
|
||||
inp.focus(); Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set.call(inp,${JSON.stringify(kw)});
|
||||
inp.dispatchEvent(new Event('input',{bubbles:true})); inp.dispatchEvent(new Event('change',{bubbles:true}));
|
||||
const b=[...m.querySelectorAll('button')].find(x=>/^\\s*搜索\\s*$/.test(x.innerText||''));
|
||||
if(b) for(const ev of ['mousedown','mouseup','click']) b.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window}));
|
||||
return 'searched';})()`);
|
||||
if (r !== 'searched') return r;
|
||||
await wait(4000);
|
||||
const pick = await c.evalJS(`(()=>{const m=[...document.querySelectorAll('.ant-modal')].filter(e=>e.offsetParent!==null).pop();
|
||||
if(!m)return'no-modal'; const its=[...m.querySelectorAll('.search-result-item')];
|
||||
if(!its.length)return'no-result';
|
||||
const BAD=/二手|Barang Terpakai|Second|Used|Pre-?owned|Refurb/i;
|
||||
const texts=its.map(e=>(e.innerText||'').replace(/\\s+/g,' ').trim());
|
||||
let idx=texts.findIndex(t=>!BAD.test(t));
|
||||
if(idx<0) idx=0;
|
||||
const hit=its[idx];
|
||||
for(const ev of ['mousedown','mouseup','click']) hit.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window}));
|
||||
return 'picked['+idx+'/'+texts.length+']:'+texts[idx];})()`);
|
||||
await wait(4500);
|
||||
return pick;
|
||||
}
|
||||
|
||||
// 2b. 多关键词回退 + 失败即中止
|
||||
async function pickCategoryAny(kws) {
|
||||
const tried = [];
|
||||
for (const kw of kws) {
|
||||
const r = String(await pickCategory(kw));
|
||||
tried.push(kw + '\u2192' + r.slice(0, 45));
|
||||
if (!/no-result|no-input|no-modal|no-btn/.test(r)) return { r, tried };
|
||||
await c.evalJS(`(()=>{const m=[...document.querySelectorAll('.ant-modal')].filter(e=>e.offsetParent!==null).pop();
|
||||
if(m){const x=m.querySelector('.ant-modal-close'); if(x&&x.offsetParent!==null)x.click();} return 1;})()`);
|
||||
await wait(1500);
|
||||
}
|
||||
return { r: 'ALL-FAILED', tried };
|
||||
}
|
||||
|
||||
// 3. 直填 store
|
||||
const setStore = (js) => c.evalJS(js);
|
||||
|
||||
log('=== TikTok 建品 ===', OID, IN.title.slice(0, 50));
|
||||
log('1) 店铺:', await pickShop());
|
||||
|
||||
const kw = CAT_KW || IN.cat_kw || IN.title.split(/[ ,]+/).slice(0, 2).join(' ');
|
||||
const catRes = await pickCategoryAny([kw].concat(IN.cat_fb || []));
|
||||
log('2) 分类:', SAN(String(catRes.r)).slice(0, 110), '| 尝试:', catRes.tried.join(' / '));
|
||||
if (/ALL-FAILED|no-result|no-input|no-btn/.test(String(catRes.r))) { log('\u274c 分类未选中,跳过保存'); await c.shot('/tmp/tk_fail_' + OID + '.jpeg').catch(() => {}); process.exit(2); }
|
||||
|
||||
// 4. 文案
|
||||
const desc = IN.bullets.map(b => '• ' + b).join('<br>') + '<br><br>Keywords: ' + (IN.keywords || '');
|
||||
const wr = await setStore(`(()=>{const p=document.querySelector('#app').__vue_app__.config.globalProperties.$pinia;
|
||||
const f=p._s.get('tiktokGlobalAddProductStore').$state.formState;
|
||||
f.productName=${JSON.stringify(IN.title)};
|
||||
f.keyProductFeatures=${JSON.stringify(IN.bullets.slice(0, 5))};
|
||||
f.searchTerms=${JSON.stringify((IN.keywords || '').split(',').map(s => s.trim()).filter(Boolean).slice(0, 10))};
|
||||
f.description='<style>img{display: block}p{margin-block-start: 0; margin-block-end: 0}</style>'+${JSON.stringify(desc)};
|
||||
return 'ok';})()`);
|
||||
log('3) 文案:', wr, '| 标长', IN.title.length);
|
||||
|
||||
// 5. 变种属性
|
||||
const vr = await c.evalJS(`(()=>{
|
||||
const h=[...document.querySelectorAll('*')].filter(e=>e.offsetParent!==null&&/^\\s*变种属性\\s*$/.test((e.innerText||'').trim())).pop();
|
||||
if(!h)return'no-sec'; let box=h;
|
||||
for(let i=0;i<6&&box.parentElement;i++){ box=box.parentElement; if(box.querySelector('input[class*="!w-200"]'))break; }
|
||||
const inp=box.querySelector('input[class*="!w-200"]'); if(!inp)return'no-inp';
|
||||
inp.focus(); Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set.call(inp,${JSON.stringify(VAR_VAL)});
|
||||
inp.dispatchEvent(new Event('input',{bubbles:true})); inp.dispatchEvent(new Event('change',{bubbles:true}));
|
||||
inp.dispatchEvent(new KeyboardEvent('keydown',{key:'Enter',code:'Enter',keyCode:13,which:13,bubbles:true}));
|
||||
const btn=[...box.querySelectorAll('button,a,span')].find(e=>/^\\s*(添加|Add)\\s*$/.test(e.innerText||''));
|
||||
if(btn) for(const ev of ['mousedown','mouseup','click']) btn.dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window}));
|
||||
return 'ok';})()`);
|
||||
log('4) 变种属性:', vr, VAR_VAL);
|
||||
await wait(3500);
|
||||
|
||||
// 6. SKU 价格/库存
|
||||
const SKU = 'AM-' + OID;
|
||||
const sr = await c.evalJS(`(()=>{
|
||||
const setV=(el,v)=>{ Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set.call(el,String(v));
|
||||
el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); el.dispatchEvent(new Event('blur',{bubbles:true})); };
|
||||
const tbl=[...document.querySelectorAll('table')].filter(t=>t.offsetParent!==null).find(t=>[...t.querySelectorAll('th')].some(h=>/本地展示价/.test(h.innerText||'')));
|
||||
if(!tbl)return'no-table';
|
||||
const ths=[...tbl.querySelectorAll('th')].map(e=>(e.innerText||'').replace(/\\s+/g,' ').trim());
|
||||
const rows=[...tbl.querySelectorAll('tbody tr')].filter(x=>x.querySelectorAll('input').length);
|
||||
const done=[];
|
||||
rows.forEach((tr,ri)=>{ [...tr.querySelectorAll('td')].forEach((td,ci)=>{ const name=ths[ci]||''; const ins=[...td.querySelectorAll('input')];
|
||||
if(/^SKU/i.test(name)&&ins[0]&&!ins[0].value){ setV(ins[0],${JSON.stringify(SKU)}+(rows.length>1?('-'+ri):'')); done.push('sku'); }
|
||||
if(/本地展示价/.test(name)&&ins[0]&&!ins[0].value){ setV(ins[0],${JSON.stringify(String(IN.price_myr))}); done.push('price'); }
|
||||
if(/^库存/.test(name)&&ins[0]&&!ins[0].value){ setV(ins[0],'999'); done.push('stock'); } }); });
|
||||
return 'rows'+rows.length+':'+[...new Set(done)].join(',');})()`);
|
||||
log('5) SKU:', sr, '| MYR', IN.price_myr);
|
||||
await wait(2000);
|
||||
|
||||
// 7. 重量 + 尺寸
|
||||
const setItem = (rx, sel, val) => c.evalJS(`(()=>{
|
||||
const it=[...document.querySelectorAll('.ant-form-item')].filter(e=>e.offsetParent!==null).find(x=>{const l=x.querySelector('label'); return l&&new RegExp(${JSON.stringify(rx)}).test(l.innerText||'');});
|
||||
const el=it?it.querySelector(${JSON.stringify(sel)}):null; if(!el)return'nf';
|
||||
const proto=el.tagName==='TEXTAREA'?window.HTMLTextAreaElement.prototype:window.HTMLInputElement.prototype;
|
||||
Object.getOwnPropertyDescriptor(proto,'value').set.call(el, ${JSON.stringify(String(val))});
|
||||
el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); el.dispatchEvent(new Event('blur',{bubbles:true})); return 'ok';})()`);
|
||||
log('6) 重量:', await setItem('重量', 'input:not([type=hidden])', IN.weight));
|
||||
const dim = await c.evalJS(`(()=>{
|
||||
const it=[...document.querySelectorAll('.ant-form-item')].filter(e=>e.offsetParent!==null).find(x=>{const l=x.querySelector('label'); return l&&/尺寸规格/.test(l.innerText||'');});
|
||||
if(!it)return'nf'; const ins=[...it.querySelectorAll('input')];
|
||||
const setV=(el,v)=>{ Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype,'value').set.call(el,String(v));
|
||||
el.dispatchEvent(new Event('input',{bubbles:true})); el.dispatchEvent(new Event('change',{bubbles:true})); el.dispatchEvent(new Event('blur',{bubbles:true})); };
|
||||
const L=ins.find(i=>i.placeholder==='长')||ins[0], W2=ins.find(i=>i.placeholder==='宽')||ins[1], H=ins.find(i=>i.placeholder==='高')||ins[2];
|
||||
if(L)setV(L,${DIMS.L}); if(W2)setV(W2,${DIMS.Wi}); if(H)setV(H,${DIMS.H});
|
||||
return 'ok:'+ins.length;})()`);
|
||||
log('7) 尺寸:', dim, JSON.stringify(DIMS));
|
||||
|
||||
// 8. 图片
|
||||
const ir = await c.evalJS(`(()=>{const p=document.querySelector('#app').__vue_app__.config.globalProperties.$pinia;
|
||||
const st=p._s.get('tiktokGlobalImgStore').$state;
|
||||
const urls=${JSON.stringify(IN.imgs)};
|
||||
st.formState.mainImage=urls.map((u,i)=>({url:u,imgUrl:u,name:'img'+(i+1)+'.jpg',width:800,height:800,checked:true}));
|
||||
return 'imgs:'+st.formState.mainImage.length;})()`);
|
||||
log('8) 图片:', ir, '(共', IN.imgs.length, ')');
|
||||
await wait(2500);
|
||||
|
||||
// 9. 来源URL
|
||||
log('9) 来源URL:', await setItem('来源URL', 'input:not([type=hidden])', 'https://detail.1688.com/offer/' + OID + '.html'));
|
||||
await wait(1200);
|
||||
|
||||
// 10. 保存
|
||||
const before = await c.evalJS(`(()=>{const p=document.querySelector('#app').__vue_app__.config.globalProperties.$pinia;
|
||||
const b=p._s.get('tiktokGlobalAddBasicStore').$state;
|
||||
return JSON.stringify({shopId:b.formState.shopId, cat:b.formState.categoryId, site:b.site});})()`);
|
||||
log('10) 保存前状态:', before);
|
||||
const sv = await c.evalJS(`(()=>{const b=[...document.querySelectorAll('button,a,span')].filter(e=>e.offsetParent!==null&&/^\\s*保存\\s*$/.test(e.innerText||''));
|
||||
if(!b.length)return'nf'; for(const ev of ['mousedown','mouseup','click']) b[b.length-1].dispatchEvent(new MouseEvent(ev,{bubbles:true,cancelable:true,view:window})); return 'clicked';})()`);
|
||||
log('11) 保存点击:', sv);
|
||||
await wait(9000);
|
||||
const msg = await c.evalJS(`(()=>{const ms=[...document.querySelectorAll('.ant-message-notice,.ant-notification-notice,.ant-modal')].filter(e=>e.offsetParent!==null)
|
||||
.map(e=>(e.innerText||'').replace(/\\s+/g,' ').trim().slice(0,160)).filter(Boolean);
|
||||
return JSON.stringify({url:location.href, msgs:ms.slice(0,4)});})()`);
|
||||
log('12) 结果:', SAN(String(msg)).slice(0, 400));
|
||||
await c.shot('/tmp/tk_pilot.jpeg').catch(() => {});
|
||||
process.exit(0);
|
||||
Reference in new issue
Block a user