feat: 支持秒杀活动

This commit is contained in:
richarjiang
2026-04-09 10:24:44 +08:00
parent 23bdd05811
commit 74551085e3
29 changed files with 3521 additions and 760 deletions

View File

@@ -45,3 +45,16 @@ export enum OrderStatus {
PAID = 'PAID',
REFUNDED = 'REFUNDED',
}
// ===== FlashSale =====
export enum FlashSaleStatus {
DRAFT = 'DRAFT',
ACTIVE = 'ACTIVE',
ENDED = 'ENDED',
}
export enum FlashSaleOrderStatus {
RESERVED = 'RESERVED',
PAID = 'PAID',
EXPIRED = 'EXPIRED',
}

View File

@@ -7,6 +7,8 @@ export {
TimeSlotSource,
BookingStatus,
OrderStatus,
FlashSaleStatus,
FlashSaleOrderStatus,
} from './enums'
// Constants
@@ -54,4 +56,13 @@ export type {
PaginatedData,
PaginatedResponse,
PaginationQuery,
FlashSale,
FlashSaleListItem,
FlashSaleDetail,
FlashSaleAdminItem,
CreateFlashSaleDto,
UpdateFlashSaleDto,
FlashSalePurchaseResponse,
} from './types/index'
export { FlashSalePhase } from './types/index'

View File

@@ -0,0 +1,97 @@
import { FlashSaleStatus, FlashSaleOrderStatus, CardTypeCategory } from '../enums'
// ── Computed sale phase (derived from server time) ──────────
export enum FlashSalePhase {
UPCOMING = 'UPCOMING',
ONGOING = 'ONGOING',
SOLD_OUT = 'SOLD_OUT',
ENDED = 'ENDED',
}
// ── Core entity ─────────────────────────────────────────────
export interface FlashSale {
readonly id: string
readonly cardTypeId: string
readonly title: string
readonly originalPrice: number
readonly flashPrice: number
readonly totalStock: number
readonly soldCount: number
readonly startTime: string
readonly endTime: string
readonly status: FlashSaleStatus
readonly description: string | null
readonly sortOrder: number
readonly createdAt: string
readonly updatedAt: string
}
// ── User-facing list item (home page) ───────────────────────
export interface FlashSaleListItem extends FlashSale {
readonly phase: FlashSalePhase
readonly remainingStock: number
readonly cardType: {
readonly name: string
readonly type: CardTypeCategory
readonly totalTimes: number | null
readonly durationDays: number
}
}
// ── Detail (includes user participation status) ─────────────
export interface FlashSaleDetail extends FlashSaleListItem {
readonly hasParticipated: boolean
readonly userOrderStatus: FlashSaleOrderStatus | null
readonly serverTime: string
}
// ── Admin DTOs ──────────────────────────────────────────────
export interface CreateFlashSaleDto {
readonly cardTypeId: string
readonly title: string
readonly originalPrice: number
readonly flashPrice: number
readonly totalStock: number
readonly startTime: string
readonly endTime: string
readonly description?: string
readonly sortOrder?: number
}
export interface UpdateFlashSaleDto {
readonly title?: string
readonly originalPrice?: number
readonly flashPrice?: number
readonly totalStock?: number
readonly startTime?: string
readonly endTime?: string
readonly description?: string
readonly status?: FlashSaleStatus
readonly sortOrder?: number
}
// ── Purchase response ───────────────────────────────────────
export interface FlashSalePurchaseResponse {
readonly flashSaleOrderId: string
readonly order: {
readonly id: string
readonly orderNo: string
readonly amount: number
}
readonly paymentParams: {
readonly timeStamp: string
readonly nonceStr: string
readonly package: string
readonly signType: string
readonly paySign: string
}
}
// ── Admin list item ─────────────────────────────────────────
export interface FlashSaleAdminItem extends FlashSale {
readonly phase: FlashSalePhase
readonly cardType: {
readonly name: string
readonly type: CardTypeCategory
}
}

View File

@@ -7,3 +7,13 @@ export type { Booking, BookingWithDetails, BookingWithUser, BookingStatusHistory
export type { Order, OrderWithDetails, CreateOrderDto, PaymentParams, CreateOrderResponse } from './order'
export type { StudioConfig, UpdateStudioConfigDto } from './studio'
export type { ApiResponse, PaginatedData, PaginatedResponse, PaginationQuery } from './api'
export type {
FlashSale,
FlashSaleListItem,
FlashSaleDetail,
FlashSaleAdminItem,
CreateFlashSaleDto,
UpdateFlashSaleDto,
FlashSalePurchaseResponse,
} from './flash-sale'
export { FlashSalePhase } from './flash-sale'