feat: 导入 16 枚图章并重构图册为 4x4 圆形布局
- 按 A4 排列顺序导入 16 枚真实商户图章(彩色 + 灰色)到数据库 - 图章素材存放于 packages/server/uploads/stamps/,命名与 sortOrder 一致 - 图册页布局由 3 列改为 4 列,StampCard 采用圆形白底容器承托透明圆章 - 去除邮票打孔/方形渐变背景,已收集态增加金色内描边与柔光阴影 - 优化进度区与兑换按钮视觉:突出数字、显示差额提示、禁用态文案 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,63 +1,71 @@
|
||||
import { prisma } from "@stamp/shared";
|
||||
|
||||
const stampData = [
|
||||
{ name: "尹氏汤包" },
|
||||
{ name: "中国移动 5G" },
|
||||
{ name: "紫金农商银行" },
|
||||
{ name: "孟令军炒货铺" },
|
||||
{ name: "春山酒窖" },
|
||||
{ name: "金陵绣男" },
|
||||
{ name: "LBZ" },
|
||||
{ name: "二条商店" },
|
||||
{ name: "陶玉梅" },
|
||||
{ name: "芳婆糕团" },
|
||||
{ name: "书锦城创" },
|
||||
{ name: "闲鱼循环商店" },
|
||||
{ name: "闽南茶叶店" },
|
||||
{ name: "魏鬼虾神" },
|
||||
{ name: "农家小院" },
|
||||
{ name: "李记清真馆" },
|
||||
];
|
||||
|
||||
async function seed() {
|
||||
console.log("Seeding database...");
|
||||
|
||||
// Create sample stamps
|
||||
const stamps = await Promise.all([
|
||||
prisma.stamp.create({
|
||||
data: { name: "古桥印记", note: "始建于明代的石拱桥", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 1 },
|
||||
// Clear existing stamps (cascades to collections)
|
||||
await prisma.stamp.deleteMany();
|
||||
|
||||
const stamps = await Promise.all(
|
||||
stampData.map((s, idx) => {
|
||||
const pos = String(idx + 1).padStart(2, "0");
|
||||
return prisma.stamp.create({
|
||||
data: {
|
||||
name: s.name,
|
||||
imageColor: `/uploads/stamps/stamp-${pos}-color.jpg`,
|
||||
imageGrey: `/uploads/stamps/stamp-${pos}-grey.jpg`,
|
||||
sortOrder: idx + 1,
|
||||
},
|
||||
});
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "老街风韵", note: "百年历史的商业老街", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 2 },
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "园林雅趣", note: "江南古典园林", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 3 },
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "茶馆时光", note: "百年老茶馆", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 4 },
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "水乡晨曲", note: "清晨的水乡渔市", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 5 },
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "戏台余韵", note: "古戏台与昆曲", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 6 },
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "巷弄深处", note: "青石板铺就的幽深小巷", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 7 },
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "月下拱桥", note: "夜晚灯火映照的拱桥", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 8 },
|
||||
}),
|
||||
prisma.stamp.create({
|
||||
data: { name: "匠心工坊", note: "传统手工艺作坊", imageColor: "/uploads/placeholder-color.svg", imageGrey: "/uploads/placeholder-grey.svg", sortOrder: 9 },
|
||||
}),
|
||||
]);
|
||||
);
|
||||
|
||||
console.log(`Created ${stamps.length} stamps`);
|
||||
|
||||
// Create redemption rules
|
||||
const rules = await Promise.all([
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "纪念书签", description: "精美城市纪念书签一枚", threshold: 3, sortOrder: 1 },
|
||||
}),
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "手绘明信片套装", description: "一套 5 张手绘城市明信片", threshold: 5, sortOrder: 2 },
|
||||
}),
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "限定徽章礼盒", description: "城市限定版金属徽章礼盒", threshold: 7, sortOrder: 3 },
|
||||
}),
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "城市记忆礼包", description: "包含纪念 T 恤、帆布袋和城市画册", threshold: 9, sortOrder: 4 },
|
||||
}),
|
||||
]);
|
||||
// Create redemption rules if none exist
|
||||
const existingRules = await prisma.redemptionRule.count();
|
||||
if (existingRules === 0) {
|
||||
const rules = await Promise.all([
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "纪念书签", description: "精美城市纪念书签一枚", threshold: 4, sortOrder: 1 },
|
||||
}),
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "手绘明信片套装", description: "一套 5 张手绘城市明信片", threshold: 8, sortOrder: 2 },
|
||||
}),
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "限定徽章礼盒", description: "城市限定版金属徽章礼盒", threshold: 12, sortOrder: 3 },
|
||||
}),
|
||||
prisma.redemptionRule.create({
|
||||
data: { name: "城市记忆礼包", description: "包含纪念 T 恤、帆布袋和城市画册", threshold: 16, sortOrder: 4 },
|
||||
}),
|
||||
]);
|
||||
console.log(`Created ${rules.length} redemption rules`);
|
||||
} else {
|
||||
console.log(`Kept existing ${existingRules} redemption rules`);
|
||||
}
|
||||
|
||||
console.log(`Created ${rules.length} redemption rules`);
|
||||
|
||||
// Print stamp IDs for QR code testing
|
||||
console.log("\nStamp IDs for testing:");
|
||||
stamps.forEach((s) => {
|
||||
console.log(` ${s.name}: /collect/${s.id}`);
|
||||
console.log(` ${s.sortOrder}. ${s.name}: /collect/${s.id}`);
|
||||
});
|
||||
|
||||
console.log("\nSeed complete!");
|
||||
|
||||
Reference in New Issue
Block a user