diff --git a/packages/server/package.json b/packages/server/package.json index 31b49d6..1b5d42c 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -60,5 +60,8 @@ "moduleNameMapper": { "^@mp-pilates/shared(.*)$": "/../../shared/src$1" } + }, + "prisma": { + "seed": "ts-node prisma/seed.ts" } } diff --git a/packages/server/prisma/seed.ts b/packages/server/prisma/seed.ts new file mode 100644 index 0000000..3a961e4 --- /dev/null +++ b/packages/server/prisma/seed.ts @@ -0,0 +1,154 @@ +import { PrismaClient, UserRole, CardTypeCategory } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + console.log('🌱 Seeding database...') + + // 1. Studio Config + const existingConfig = await prisma.studioConfig.findFirst() + if (!existingConfig) { + await prisma.studioConfig.create({ + data: { + name: '普拉提工作室', + address: '请在管理后台设置地址', + phone: '请在管理后台设置电话', + cancelHoursLimit: 2, + photos: [], + }, + }) + console.log(' ✅ Studio config created') + } else { + console.log(' ⏭️ Studio config already exists') + } + + // 2. Card Types + const existingCards = await prisma.cardType.count() + if (existingCards === 0) { + await prisma.cardType.createMany({ + data: [ + { + name: '体验课', + type: CardTypeCategory.TRIAL, + totalTimes: 1, + durationDays: 7, + price: 9900, + originalPrice: 29900, + description: '首次体验,感受普拉提的魅力', + isActive: true, + sortOrder: 0, + }, + { + name: '私教10次卡', + type: CardTypeCategory.TIMES, + totalTimes: 10, + durationDays: 90, + price: 299900, + originalPrice: 399900, + description: '10节私教课,90天有效期', + isActive: true, + sortOrder: 1, + }, + { + name: '私教20次卡', + type: CardTypeCategory.TIMES, + totalTimes: 20, + durationDays: 180, + price: 499900, + originalPrice: 699900, + description: '20节私教课,180天有效期,更优惠', + isActive: true, + sortOrder: 2, + }, + { + name: '月卡', + type: CardTypeCategory.DURATION, + totalTimes: null, + durationDays: 30, + price: 99900, + description: '30天不限次数', + isActive: true, + sortOrder: 3, + }, + { + name: '季卡', + type: CardTypeCategory.DURATION, + totalTimes: null, + durationDays: 90, + price: 249900, + originalPrice: 299700, + description: '90天不限次数,更实惠', + isActive: true, + sortOrder: 4, + }, + ], + }) + console.log(' ✅ Card types created') + } else { + console.log(' ⏭️ Card types already exist') + } + + // 3. Admin User + const existingAdmin = await prisma.user.findFirst({ + where: { role: UserRole.ADMIN }, + }) + if (!existingAdmin) { + await prisma.user.create({ + data: { + openid: 'admin_test_openid', + nickname: '教练', + role: UserRole.ADMIN, + }, + }) + console.log(' ✅ Admin user created') + } else { + console.log(' ⏭️ Admin user already exists') + } + + // 4. Week Templates (weekdays 9-16, hourly slots) + const existingTemplates = await prisma.weekTemplate.count() + if (existingTemplates === 0) { + const timeSlots = [ + { startTime: '09:00', endTime: '10:00' }, + { startTime: '10:00', endTime: '11:00' }, + { startTime: '14:00', endTime: '15:00' }, + { startTime: '15:00', endTime: '16:00' }, + ] + + const templates = [] + // Monday to Friday (1-5) + for (let day = 1; day <= 5; day++) { + for (const slot of timeSlots) { + templates.push({ + dayOfWeek: day, + startTime: slot.startTime, + endTime: slot.endTime, + capacity: 1, + isActive: true, + }) + } + } + + // Saturday (6) — morning only + templates.push( + { dayOfWeek: 6, startTime: '09:00', endTime: '10:00', capacity: 1, isActive: true }, + { dayOfWeek: 6, startTime: '10:00', endTime: '11:00', capacity: 1, isActive: true }, + ) + + await prisma.weekTemplate.createMany({ data: templates }) + console.log(' ✅ Week templates created') + } else { + console.log(' ⏭️ Week templates already exist') + } + + console.log('🌱 Seeding complete!') +} + +main() + .catch((e) => { + console.error('❌ Seed failed:', e) + process.exit(1) + }) + .finally(async () => { + await prisma.$disconnect() + })