148 lines
4.4 KiB
TypeScript
148 lines
4.4 KiB
TypeScript
/**
|
|
* 将存量商品 / 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());
|