/** * 从 PDD 纯数字内部 SKU 的订单项回填中文映射(只读扫描 + 幂等写入)。 * * 只处理 sku_name 含中文、sku_code 为纯数字的情况; * 找不到中文名的纯数字码会列出来,等运营补映射。 * * 用法:npx tsx scripts/backfill-internal-sku-mappings.ts [--apply] */ import { closeDb, query } from '../src/db/client.js' import { upsertInternalSkuMapping } from '../src/services/fulfillment/internal-sku-mapping-service.js' async function main() { const apply = process.argv.includes('--apply') const rows = await query<{ provider: string shop_id: string sku_code: string sku_name: string total: number }>( ` SELECT o.provider, o.shop_id, oi.sku_code, MIN(oi.sku_name) AS sku_name, count(*)::int AS total FROM order_items oi JOIN orders o ON o.id = oi.order_id WHERE btrim(COALESCE(oi.manual_sku_key, '')) ~ '^[0-9]+$' AND btrim(COALESCE(oi.sku_name, '')) ~ '[一-龥]' GROUP BY 1, 2, 3 ORDER BY 5 DESC `, ) const unresolved = await query<{ provider: string shop_id: string sku_code: string total: number }>( ` SELECT o.provider, o.shop_id, oi.sku_code, count(*)::int AS total FROM order_items oi JOIN orders o ON o.id = oi.order_id WHERE btrim(COALESCE(oi.manual_sku_key, '')) ~ '^[0-9]+$' AND btrim(COALESCE(oi.sku_name, '')) !~ '[一-龥]' GROUP BY 1, 2, 3 ORDER BY 4 DESC `, ) let written = 0 for (const row of rows.rows) { if (apply) { await upsertInternalSkuMapping({ provider: row.provider, shopId: row.shop_id, matchType: 'sku_code', matchValue: row.sku_code, internalSku: row.sku_name, priority: 100, source: 'backfill', note: `从 ${row.total} 条订单项回填`, }) } if (apply) written += 1 } console.log( JSON.stringify( { apply, canBackfill: rows.rows.length, backfilled: written, unresolved: unresolved.rows, }, null, 2, ), ) } main() .catch((error) => { console.error(error) process.exitCode = 1 }) .finally(() => closeDb())