Files
mp-pilates/packages/server/prisma/schema.prisma
2026-04-06 08:38:05 +08:00

226 lines
6.2 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
}
// ===== 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[]
@@map("users")
}
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[]
@@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")
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])
@@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")
}