@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* 将存量商品 / SKU 的 sku_code 全部改成 DK + 6 位数字。
|
||||
* 已是 DK 数字码的保持不变;其余先写临时码再分配,避免唯一约束冲突。
|
||||
*
|
||||
* 用法:cd server/dukang-api && npx ts-node prisma/rewrite-sku-codes-dk.ts
|
||||
*/
|
||||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
const PREFIX = 'DK';
|
||||
const PAD = 6;
|
||||
const RE = /^DK(\d+)$/;
|
||||
|
||||
function isDk(code: string) {
|
||||
return RE.test(code);
|
||||
}
|
||||
|
||||
function formatCode(seq: number) {
|
||||
return `${PREFIX}${String(seq).padStart(PAD, '0')}`;
|
||||
}
|
||||
|
||||
async function maxExistingSeq(): Promise<number> {
|
||||
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 maxSeq;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const skus = await prisma.commonProductSku.findMany({
|
||||
orderBy: [{ productId: 'asc' }, { id: 'asc' }],
|
||||
select: { id: true, productId: true, skuCode: true, isDefault: true },
|
||||
});
|
||||
const products = await prisma.commonProductItem.findMany({
|
||||
select: { id: true, skuCode: true },
|
||||
});
|
||||
|
||||
const skuNeed = skus.filter((s) => !isDk(s.skuCode));
|
||||
const productNeed = products.filter((p) => !isDk(p.skuCode));
|
||||
console.log(`sku total=${skus.length} rewrite=${skuNeed.length}`);
|
||||
console.log(`product total=${products.length} rewrite=${productNeed.length}`);
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
for (const s of skuNeed) {
|
||||
await tx.commonProductSku.update({
|
||||
where: { id: s.id },
|
||||
data: { skuCode: `TMP${s.id.toString()}` },
|
||||
});
|
||||
}
|
||||
for (const p of productNeed) {
|
||||
await tx.commonProductItem.update({
|
||||
where: { id: p.id },
|
||||
data: { skuCode: `TMPP${p.id.toString()}` },
|
||||
});
|
||||
}
|
||||
|
||||
const seqStart = await (async () => {
|
||||
const [items, skuRows] = await Promise.all([
|
||||
tx.commonProductItem.findMany({
|
||||
where: { skuCode: { startsWith: PREFIX } },
|
||||
select: { skuCode: true },
|
||||
}),
|
||||
tx.commonProductSku.findMany({
|
||||
where: { skuCode: { startsWith: PREFIX } },
|
||||
select: { skuCode: true },
|
||||
}),
|
||||
]);
|
||||
let maxSeq = 0;
|
||||
for (const row of [...items, ...skuRows]) {
|
||||
const m = RE.exec(row.skuCode);
|
||||
if (!m) continue;
|
||||
const n = Number(m[1]);
|
||||
if (Number.isFinite(n) && n > maxSeq) maxSeq = n;
|
||||
}
|
||||
return maxSeq;
|
||||
})();
|
||||
|
||||
let seq = seqStart;
|
||||
const defaultSkuCodeByProduct = new Map<string, string>();
|
||||
|
||||
for (const s of skuNeed) {
|
||||
seq += 1;
|
||||
const code = formatCode(seq);
|
||||
await tx.commonProductSku.update({
|
||||
where: { id: s.id },
|
||||
data: { skuCode: code },
|
||||
});
|
||||
if (s.isDefault) defaultSkuCodeByProduct.set(s.productId.toString(), code);
|
||||
console.log(`sku ${s.id} ${s.skuCode} -> ${code}`);
|
||||
}
|
||||
|
||||
for (const p of productNeed) {
|
||||
const fromDefault = defaultSkuCodeByProduct.get(p.id.toString());
|
||||
let code = fromDefault;
|
||||
if (!code) {
|
||||
seq += 1;
|
||||
code = formatCode(seq);
|
||||
}
|
||||
await tx.commonProductItem.update({
|
||||
where: { id: p.id },
|
||||
data: { skuCode: code },
|
||||
});
|
||||
console.log(`product ${p.id} ${p.skuCode} -> ${code}`);
|
||||
}
|
||||
|
||||
const stillDefault = await tx.commonProductSku.findMany({
|
||||
where: { isDefault: true },
|
||||
select: { productId: true, skuCode: true },
|
||||
});
|
||||
for (const s of stillDefault) {
|
||||
if (!isDk(s.skuCode)) continue;
|
||||
await tx.commonProductItem.updateMany({
|
||||
where: { id: s.productId, NOT: { skuCode: s.skuCode } },
|
||||
data: { skuCode: s.skuCode },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const leftoverSku = await prisma.commonProductSku.count({
|
||||
where: { NOT: { skuCode: { startsWith: PREFIX } } },
|
||||
});
|
||||
const leftoverProduct = await prisma.commonProductItem.count({
|
||||
where: { NOT: { skuCode: { startsWith: PREFIX } } },
|
||||
});
|
||||
console.log(`done leftoverSku=${leftoverSku} leftoverProduct=${leftoverProduct} maxWas=${await maxExistingSeq()}`);
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(() => prisma.$disconnect());
|
||||
Reference in New Issue
Block a user