feat: add core types and mock data layer
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
export function getMonthGrid(year: number, month: number): Date[][] {
|
||||
const firstDay = new Date(year, month, 1)
|
||||
const startDay = firstDay.getDay()
|
||||
const startOffset = startDay === 0 ? -6 : 1 - startDay
|
||||
const startDate = new Date(year, month, 1 + startOffset)
|
||||
|
||||
const weeks: Date[][] = []
|
||||
for (let w = 0; w < 6; w++) {
|
||||
const week: Date[] = []
|
||||
for (let d = 0; d < 7; d++) {
|
||||
const date = new Date(startDate)
|
||||
date.setDate(startDate.getDate() + w * 7 + d)
|
||||
week.push(date)
|
||||
}
|
||||
weeks.push(week)
|
||||
}
|
||||
return weeks
|
||||
}
|
||||
|
||||
export function formatDate(date: Date): string {
|
||||
const y = date.getFullYear()
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const d = String(date.getDate()).padStart(2, '0')
|
||||
return `${y}-${m}-${d}`
|
||||
}
|
||||
|
||||
export function isSameDay(a: Date, b: Date): boolean {
|
||||
return (
|
||||
a.getFullYear() === b.getFullYear() &&
|
||||
a.getMonth() === b.getMonth() &&
|
||||
a.getDate() === b.getDate()
|
||||
)
|
||||
}
|
||||
|
||||
export function isCurrentMonth(date: Date, year: number, month: number): boolean {
|
||||
return date.getFullYear() === year && date.getMonth() === month
|
||||
}
|
||||
|
||||
export function isToday(date: Date): boolean {
|
||||
return isSameDay(date, new Date())
|
||||
}
|
||||
|
||||
export function getMonthName(month: number): string {
|
||||
const names = [
|
||||
'一月', '二月', '三月', '四月', '五月', '六月',
|
||||
'七月', '八月', '九月', '十月', '十一月', '十二月',
|
||||
]
|
||||
return names[month]
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import type { Reservation, Waiter, CreateReservationInput, UpdateReservationInput, CreateWaiterInput, UpdateWaiterInput } from './types'
|
||||
|
||||
let waiters: Waiter[] = [
|
||||
{
|
||||
id: '1',
|
||||
name: '王小明',
|
||||
gallery: [
|
||||
{ id: 'm1', type: 'image', url: '/placeholder.svg' },
|
||||
{ id: 'm2', type: 'image', url: '/placeholder.svg' },
|
||||
],
|
||||
specialty: '宴会/商务',
|
||||
commissionRate: 30,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: '李小红',
|
||||
gallery: [
|
||||
{ id: 'm3', type: 'image', url: '/placeholder.svg' },
|
||||
],
|
||||
specialty: '婚宴/生日',
|
||||
commissionRate: 25,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: '张三',
|
||||
gallery: [],
|
||||
specialty: '日常接待',
|
||||
commissionRate: 20,
|
||||
},
|
||||
]
|
||||
|
||||
let reservations: Reservation[] = [
|
||||
{ id: 'r1', customerName: '张伟', date: '2026-05-16', time: '11:00', waiterId: '1', package: '生日宴', note: '需要蛋糕' },
|
||||
{ id: 'r2', customerName: '李芳', date: '2026-05-16', time: '12:30', waiterId: '2', package: '商务宴请' },
|
||||
{ id: 'r3', customerName: '赵强', date: '2026-05-16', time: '18:00', waiterId: '1' },
|
||||
{ id: 'r4', customerName: '刘梅', date: '2026-05-20', time: '11:30', waiterId: '2', package: '婚宴' },
|
||||
{ id: 'r5', customerName: '陈先生', date: '2026-05-12', time: '10:00', waiterId: '3' },
|
||||
{ id: 'r6', customerName: '王太太', date: '2026-05-12', time: '14:00', waiterId: '3', package: '下午茶' },
|
||||
{ id: 'r7', customerName: '林总', date: '2026-05-14', time: '19:00', waiterId: '1', package: '商务宴' },
|
||||
]
|
||||
|
||||
let waiterNextId = 4
|
||||
let reservationNextId = 8
|
||||
|
||||
export function getReservationsByDate(date: string): Reservation[] {
|
||||
return reservations.filter((r) => r.date === date)
|
||||
}
|
||||
|
||||
export function getReservationsByMonth(year: number, month: number): Reservation[] {
|
||||
const prefix = `${year}-${String(month + 1).padStart(2, '0')}`
|
||||
return reservations.filter((r) => r.date.startsWith(prefix))
|
||||
}
|
||||
|
||||
export function createReservation(input: CreateReservationInput): Reservation {
|
||||
const reservation: Reservation = {
|
||||
id: `r${reservationNextId++}`,
|
||||
...input,
|
||||
}
|
||||
reservations.push(reservation)
|
||||
return reservation
|
||||
}
|
||||
|
||||
export function updateReservation(id: string, input: UpdateReservationInput): Reservation | null {
|
||||
const index = reservations.findIndex((r) => r.id === id)
|
||||
if (index === -1) return null
|
||||
reservations[index] = { ...reservations[index], ...input }
|
||||
return reservations[index]
|
||||
}
|
||||
|
||||
export function deleteReservation(id: string): boolean {
|
||||
const index = reservations.findIndex((r) => r.id === id)
|
||||
if (index === -1) return false
|
||||
reservations.splice(index, 1)
|
||||
return true
|
||||
}
|
||||
|
||||
export function getWaiters(): Waiter[] {
|
||||
return [...waiters]
|
||||
}
|
||||
|
||||
export function getWaiterById(id: string): Waiter | undefined {
|
||||
return waiters.find((w) => w.id === id)
|
||||
}
|
||||
|
||||
export function createWaiter(input: CreateWaiterInput): Waiter {
|
||||
const waiter: Waiter = {
|
||||
id: String(waiterNextId++),
|
||||
...input,
|
||||
}
|
||||
waiters.push(waiter)
|
||||
return waiter
|
||||
}
|
||||
|
||||
export function updateWaiter(id: string, input: UpdateWaiterInput): Waiter | null {
|
||||
const index = waiters.findIndex((w) => w.id === id)
|
||||
if (index === -1) return null
|
||||
waiters[index] = { ...waiters[index], ...input }
|
||||
return waiters[index]
|
||||
}
|
||||
|
||||
export function deleteWaiter(id: string): boolean {
|
||||
const index = waiters.findIndex((w) => w.id === id)
|
||||
if (index === -1) return false
|
||||
waiters.splice(index, 1)
|
||||
reservations = reservations.filter((r) => r.waiterId !== id)
|
||||
return true
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
export type MediaType = 'image' | 'video'
|
||||
|
||||
export interface Media {
|
||||
id: string
|
||||
type: MediaType
|
||||
url: string
|
||||
}
|
||||
|
||||
export interface Waiter {
|
||||
id: string
|
||||
name: string
|
||||
gallery: Media[]
|
||||
specialty: string
|
||||
commissionRate: number
|
||||
}
|
||||
|
||||
export interface Reservation {
|
||||
id: string
|
||||
customerName: string
|
||||
date: string
|
||||
time: string
|
||||
waiterId: string
|
||||
package?: string
|
||||
note?: string
|
||||
}
|
||||
|
||||
export interface CreateReservationInput {
|
||||
customerName: string
|
||||
date: string
|
||||
time: string
|
||||
waiterId: string
|
||||
package?: string
|
||||
note?: string
|
||||
}
|
||||
|
||||
export interface UpdateReservationInput extends Partial<CreateReservationInput> {}
|
||||
|
||||
export interface CreateWaiterInput {
|
||||
name: string
|
||||
gallery: Media[]
|
||||
specialty: string
|
||||
commissionRate: number
|
||||
}
|
||||
|
||||
export interface UpdateWaiterInput extends Partial<CreateWaiterInput> {}
|
||||
Reference in New Issue
Block a user