diff --git a/packages/server/src/scripts/rename-prize-names.ts b/packages/server/src/scripts/rename-prize-names.ts new file mode 100644 index 0000000..3484414 --- /dev/null +++ b/packages/server/src/scripts/rename-prize-names.ts @@ -0,0 +1,73 @@ +import { prisma } from "@stamp/shared"; + +const OLD_SUFFIX = "· 纪念章"; +const NEW_SUFFIX = "· 专属奖品"; +const OLD_DESC_RE = /^在「(.+)」集到的专属纪念奖品$/; +const NEW_DESC = (brand: string) => `在「${brand}」可兑换的专属奖品`; + +async function main() { + const apply = process.argv.includes("--apply"); + + const prizes = await prisma.prize.findMany(); + const prizeNameHits = prizes.filter((p) => p.name.endsWith(OLD_SUFFIX)); + const prizeDescHits = prizes.filter((p) => p.description && OLD_DESC_RE.test(p.description)); + + const redemptions = await prisma.redemption.findMany(); + const redemptionHits = redemptions.filter((r) => r.prizeName.endsWith(OLD_SUFFIX)); + + console.log(`=== Prize.name (${prizeNameHits.length}) ===`); + prizeNameHits.slice(0, 20).forEach((p) => { + const next = p.name.slice(0, -OLD_SUFFIX.length) + NEW_SUFFIX; + console.log(` "${p.name}" → "${next}"`); + }); + if (prizeNameHits.length > 20) console.log(` ...共 ${prizeNameHits.length} 条`); + + console.log(`\n=== Prize.description (${prizeDescHits.length}) ===`); + prizeDescHits.slice(0, 20).forEach((p) => { + const m = p.description!.match(OLD_DESC_RE)!; + console.log(` "${p.description}" → "${NEW_DESC(m[1])}"`); + }); + if (prizeDescHits.length > 20) console.log(` ...共 ${prizeDescHits.length} 条`); + + console.log(`\n=== Redemption.prizeName (${redemptionHits.length}) ===`); + redemptionHits.slice(0, 20).forEach((r) => { + const next = r.prizeName.slice(0, -OLD_SUFFIX.length) + NEW_SUFFIX; + console.log(` "${r.prizeName}" → "${next}"`); + }); + if (redemptionHits.length > 20) console.log(` ...共 ${redemptionHits.length} 条`); + + const total = prizeNameHits.length + prizeDescHits.length + redemptionHits.length; + if (total === 0) { + console.log("\n✓ 没有需要替换的记录。"); + return; + } + + if (!apply) { + console.log(`\nDRY RUN — 共 ${total} 条待改。传入 --apply 执行写入。`); + return; + } + + console.log(`\n正在写入...`); + await prisma.$transaction(async (tx) => { + for (const p of prizeNameHits) { + const next = p.name.slice(0, -OLD_SUFFIX.length) + NEW_SUFFIX; + await tx.prize.update({ where: { id: p.id }, data: { name: next } }); + } + for (const p of prizeDescHits) { + const m = p.description!.match(OLD_DESC_RE)!; + await tx.prize.update({ where: { id: p.id }, data: { description: NEW_DESC(m[1]) } }); + } + for (const r of redemptionHits) { + const next = r.prizeName.slice(0, -OLD_SUFFIX.length) + NEW_SUFFIX; + await tx.redemption.update({ where: { id: r.id }, data: { prizeName: next } }); + } + }); + console.log(`\n完成。已更新 ${total} 条。`); +} + +main() + .catch((e) => { + console.error(e); + process.exit(1); + }) + .finally(() => prisma.$disconnect()); diff --git a/packages/server/src/seed.ts b/packages/server/src/seed.ts index 69aae4f..65a4445 100644 --- a/packages/server/src/seed.ts +++ b/packages/server/src/seed.ts @@ -36,8 +36,8 @@ async function seed() { sortOrder: idx + 1, prize: { create: { - name: `${s.name} · 纪念章`, - description: `在「${s.name}」集到的专属纪念奖品`, + name: `${s.name} · 专属奖品`, + description: `在「${s.name}」可兑换的专属奖品`, stock: 100, enabled: true, }, diff --git a/packages/web/src/admin/StampForm.tsx b/packages/web/src/admin/StampForm.tsx index 60de8ae..5bef333 100644 --- a/packages/web/src/admin/StampForm.tsx +++ b/packages/web/src/admin/StampForm.tsx @@ -229,7 +229,7 @@ export default function StampForm({ open, id, onClose, onSaved }: Props) { setPrizeName(e.target.value)} - placeholder="如:朝天宫纪念书签" + placeholder="如:品牌 8 折券 / 定制书签" className={fieldCls} />