Files
mp-pilates/packages/server/prisma/schema.prisma
2026-04-12 21:44:44 +08:00

313 lines
9.4 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
// ===== Enums =====
enum UserRole {
MEMBER
ADMIN
}
enum CardTypeCategory {
TIMES
DURATION
TRIAL
}
enum MembershipStatus {
ACTIVE
EXPIRED
USED_UP
}
enum TimeSlotStatus {
OPEN
FULL
CLOSED
}
enum TimeSlotSource {
TEMPLATE
MANUAL
}
enum BookingStatus {
PENDING_CONFIRMATION
CONFIRMED
CANCELLED
COMPLETED
NO_SHOW
}
enum OrderStatus {
PENDING
PAID
REFUNDED
}
enum FlashSaleStatus {
DRAFT
ACTIVE
ENDED
}
enum FlashSaleOrderStatus {
RESERVED
PAID
EXPIRED
}
// ===== Models =====
model User {
id String @id @default(uuid())
openid String @unique
unionid String?
phone String?
nickname String @default("")
avatarUrl String? @map("avatar_url")
role UserRole @default(MEMBER)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
memberships Membership[]
bookings Booking[]
orders Order[]
flashSaleOrders FlashSaleOrder[]
subscriptionMessageConsents SubscriptionMessageConsent[]
@@map("users")
}
model SubscriptionMessageConsent {
id String @id @default(uuid())
userId String @map("user_id")
templateId String @map("template_id")
scene String
totalRequestCount Int @default(0) @map("total_request_count")
acceptCount Int @default(0) @map("accept_count")
rejectCount Int @default(0) @map("reject_count")
banCount Int @default(0) @map("ban_count")
filterCount Int @default(0) @map("filter_count")
sentCount Int @default(0) @map("sent_count")
lastResult String @map("last_result")
lastRequestedAt DateTime @default(now()) @map("last_requested_at")
lastSentAt DateTime? @map("last_sent_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id])
@@unique([userId, templateId, scene])
@@index([userId])
@@index([scene])
@@map("subscription_message_consents")
}
model CardType {
id String @id @default(uuid())
name String
type CardTypeCategory
totalTimes Int? @map("total_times")
durationDays Int @map("duration_days")
price Decimal @db.Decimal(10, 0)
originalPrice Decimal? @map("original_price") @db.Decimal(10, 0)
description String?
isActive Boolean @default(true) @map("is_active")
sortOrder Int @default(0) @map("sort_order")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
memberships Membership[]
orders Order[]
flashSales FlashSale[]
@@map("card_types")
}
model Membership {
id String @id @default(uuid())
userId String @map("user_id")
cardTypeId String @map("card_type_id")
remainingTimes Int? @map("remaining_times")
startDate DateTime @map("start_date")
expireDate DateTime @map("expire_date")
status MembershipStatus @default(ACTIVE)
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id])
cardType CardType @relation(fields: [cardTypeId], references: [id])
bookings Booking[]
@@index([userId])
@@index([status])
@@map("memberships")
}
model WeekTemplate {
id String @id @default(uuid())
dayOfWeek Int @map("day_of_week")
startTime String @map("start_time")
endTime String @map("end_time")
capacity Int @default(1)
isActive Boolean @default(true) @map("is_active")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
timeSlots TimeSlot[]
@@map("week_templates")
}
model TimeSlot {
id String @id @default(uuid())
date DateTime @db.Date
startTime String @map("start_time")
endTime String @map("end_time")
capacity Int @default(1)
bookedCount Int @default(0) @map("booked_count")
status TimeSlotStatus @default(OPEN)
source TimeSlotSource @default(TEMPLATE)
templateId String? @map("template_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
template WeekTemplate? @relation(fields: [templateId], references: [id])
bookings Booking[]
@@unique([date, startTime, endTime])
@@index([date])
@@index([status])
@@map("time_slots")
}
model Booking {
id String @id @default(uuid())
userId String @map("user_id")
timeSlotId String @map("time_slot_id")
membershipId String @map("membership_id")
status BookingStatus @default(PENDING_CONFIRMATION)
cancelledAt DateTime? @map("cancelled_at")
confirmedAt DateTime? @map("confirmed_at")
completedAt DateTime? @map("completed_at")
operatorId String? @map("operator_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id])
timeSlot TimeSlot @relation(fields: [timeSlotId], references: [id])
membership Membership @relation(fields: [membershipId], references: [id])
statusHistory BookingStatusHistory[]
@@unique([userId, timeSlotId])
@@index([userId])
@@index([status])
@@map("bookings")
}
model BookingStatusHistory {
id String @id @default(uuid())
bookingId String @map("booking_id")
fromStatus String? @map("from_status")
toStatus String @map("to_status")
operatorId String? @map("operator_id")
remark String?
createdAt DateTime @default(now()) @map("created_at")
booking Booking @relation(fields: [bookingId], references: [id])
@@index([bookingId])
@@map("booking_status_history")
}
model Order {
id String @id @default(uuid())
userId String @map("user_id")
cardTypeId String @map("card_type_id")
orderNo String @unique @map("order_no")
amount Decimal @db.Decimal(10, 0)
status OrderStatus @default(PENDING)
wxTransactionId String? @map("wx_transaction_id")
paidAt DateTime? @map("paid_at")
flashSaleId String? @map("flash_sale_id")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
user User @relation(fields: [userId], references: [id])
cardType CardType @relation(fields: [cardTypeId], references: [id])
flashSaleOrder FlashSaleOrder?
@@index([userId])
@@index([status])
@@map("orders")
}
model StudioConfig {
id String @id @default(uuid())
name String
logo String?
bannerUrl String? @map("banner_url")
address String @default("")
phone String @default("")
latitude Decimal? @db.Decimal(10, 7)
longitude Decimal? @db.Decimal(10, 7)
cancelHoursLimit Int @default(2) @map("cancel_hours_limit")
photos Json @default("[]")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("studio_config")
}
model FlashSale {
id String @id @default(uuid())
cardTypeId String @map("card_type_id")
title String
originalPrice Decimal @map("original_price") @db.Decimal(10, 0)
flashPrice Decimal @map("flash_price") @db.Decimal(10, 0)
totalStock Int @map("total_stock")
soldCount Int @default(0) @map("sold_count")
startTime DateTime @map("start_time")
endTime DateTime @map("end_time")
status FlashSaleStatus @default(DRAFT)
description String? @db.Text
sortOrder Int @default(0) @map("sort_order")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
cardType CardType @relation(fields: [cardTypeId], references: [id])
orders FlashSaleOrder[]
@@index([status, startTime, endTime])
@@map("flash_sales")
}
model FlashSaleOrder {
id String @id @default(uuid())
flashSaleId String @map("flash_sale_id")
userId String @map("user_id")
orderId String? @unique @map("order_id")
status FlashSaleOrderStatus @default(RESERVED)
reservedAt DateTime @default(now()) @map("reserved_at")
paidAt DateTime? @map("paid_at")
expiredAt DateTime? @map("expired_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
flashSale FlashSale @relation(fields: [flashSaleId], references: [id])
user User @relation(fields: [userId], references: [id])
order Order? @relation(fields: [orderId], references: [id])
@@unique([flashSaleId, userId])
@@index([userId])
@@index([status])
@@map("flash_sale_orders")
}