/** * v3.5.4:为尚无 SKU 的商品回填默认 SKU(与 migrate-product-sku-v354.sql 一致) * 用法:cd server/dukang-api && npx ts-node prisma/backfill-product-skus.ts */ import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); const PREFIX = 'DK'; const PAD = 6; const RE = /^DK(\d+)$/; async function nextDkCode() { const [items, skus] = await Promise.all([ prisma.commonProductItem.findMany({ where: { skuCode: { startsWith: PREFIX } }, select: { skuCode: true }, }), prisma.commonProductSku.findMany({ where: { skuCode: { startsWith: PREFIX } }, select: { skuCode: true }, }), ]); let maxSeq = 0; for (const row of [...items, ...skus]) { const m = RE.exec(row.skuCode); if (!m) continue; const n = Number(m[1]); if (Number.isFinite(n) && n > maxSeq) maxSeq = n; } return `${PREFIX}${String(maxSeq + 1).padStart(PAD, '0')}`; } async function main() { const products = await prisma.commonProductItem.findMany({ include: { skus: { select: { id: true }, take: 1 } }, }); let created = 0; for (const p of products) { if (p.skus.length > 0) continue; const skuCode = RE.test(p.skuCode) ? p.skuCode : await nextDkCode(); await prisma.commonProductSku.create({ data: { productId: p.id, skuCode, barcode69: p.barcode69, specKey: '', specText: p.spec, price: p.price, benefitAmount: p.benefitAmount, status: p.status, allowOnSitePickup: p.allowOnSitePickup, allowOnlinePurchase: p.allowOnlinePurchase, allowCrossCityDelivery: p.allowCrossCityDelivery, saleUnit: 'BOTTLE', bottlesPerUnit: 1, isDefault: true, sortOrder: 0, }, }); if (p.skuCode !== skuCode) { await prisma.commonProductItem.update({ where: { id: p.id }, data: { skuCode }, }); } created += 1; console.log(`created default sku for product ${p.id} ${skuCode}`); } console.log(`done, created=${created}, scanned=${products.length}`); } main() .catch((e) => { console.error(e); process.exit(1); }) .finally(() => prisma.$disconnect());