128 lines
4.1 KiB
JavaScript
128 lines
4.1 KiB
JavaScript
import { courseCatalogMock } from './mockData.js'
|
|
|
|
function clone(value) {
|
|
return JSON.parse(JSON.stringify(value))
|
|
}
|
|
|
|
export function getDefaultCourseCatalog() {
|
|
return clone(courseCatalogMock.courses)
|
|
}
|
|
|
|
export function mergeCourseCatalog(saved) {
|
|
const defaults = getDefaultCourseCatalog()
|
|
if (!saved?.length) return defaults
|
|
return saved.map((item, i) => ({ ...defaults[i], ...item }))
|
|
}
|
|
|
|
function parseCourseStart(course) {
|
|
const str = `${course.date} ${course.startTime}`.replace(/-/g, '/')
|
|
return new Date(str)
|
|
}
|
|
|
|
function getPeriod(hour) {
|
|
if (hour < 12) return 'morning'
|
|
if (hour < 18) return 'afternoon'
|
|
return 'evening'
|
|
}
|
|
|
|
export function filterCourses(courses, filters = {}) {
|
|
const {
|
|
date = '',
|
|
weekDates = [],
|
|
type = 'all',
|
|
coach = '全部',
|
|
period = 'all'
|
|
} = filters
|
|
|
|
return courses.filter((c) => {
|
|
if (type !== 'all' && c.type !== type) return false
|
|
if (coach !== '全部' && c.coach !== coach) return false
|
|
if (period !== 'all' && c.period !== period) return false
|
|
if (date && c.date !== date) {
|
|
if (!weekDates.length || !weekDates.includes(c.date)) return false
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
|
|
export function getCourseById(store, id) {
|
|
const course = (store.courseCatalog || []).find((c) => c.id === Number(id))
|
|
return course ? { ...course } : null
|
|
}
|
|
|
|
export function canCancelBooking(item) {
|
|
if (!item?.courseDate || !item?.startTime) return !!item?.canCancel
|
|
const start = new Date(`${item.courseDate} ${item.startTime}`.replace(/-/g, '/'))
|
|
const diff = start - Date.now()
|
|
return diff >= 2 * 3600000
|
|
}
|
|
|
|
export function bookCourse(store, courseId) {
|
|
const course = store.courseCatalog.find((c) => c.id === Number(courseId))
|
|
if (!course) return { ok: false, message: '课程不存在' }
|
|
if (course.enrolled >= course.capacity) return { ok: false, message: '课程已约满' }
|
|
const exists = store.ongoingBookings.some((b) => b.courseId === course.id)
|
|
if (exists) return { ok: false, message: '您已预约该课程' }
|
|
|
|
course.enrolled += 1
|
|
const nextId = store.ongoingBookings.reduce((m, b) => Math.max(m, b.id || 0), 0) + 1
|
|
const parts = course.date.split('-')
|
|
const booking = {
|
|
id: nextId,
|
|
courseId: course.id,
|
|
title: course.title,
|
|
banner: course.banner,
|
|
status: 'booked',
|
|
statusLabel: '已预约',
|
|
schedule: `${parts[1]}月${parts[2]}日 ${course.startTime}-${course.endTime}`,
|
|
dateDay: parts[2],
|
|
dateMonth: `月${parts[2]}日`,
|
|
timeRange: `${course.startTime}-${course.endTime}`,
|
|
courseDate: course.date,
|
|
startTime: course.startTime,
|
|
coach: course.coach,
|
|
coachShort: course.coach.replace('教练', ''),
|
|
location: course.location,
|
|
footerText: `可取消(需提前2小时,截止 ${parts[1]}/${parts[2]} ${course.startTime} 前2小时)`,
|
|
canCancel: true,
|
|
type: course.type
|
|
}
|
|
store.ongoingBookings.unshift(booking)
|
|
return { ok: true, message: '预约成功', booking }
|
|
}
|
|
|
|
export function getWeekDates(baseDateStr) {
|
|
const base = baseDateStr ? new Date(baseDateStr.replace(/-/g, '/')) : new Date()
|
|
const day = base.getDay() || 7
|
|
const monday = new Date(base)
|
|
monday.setDate(base.getDate() - day + 1)
|
|
const dates = []
|
|
for (let i = 0; i < 7; i += 1) {
|
|
const d = new Date(monday)
|
|
d.setDate(monday.getDate() + i)
|
|
dates.push(formatIso(d))
|
|
}
|
|
return dates
|
|
}
|
|
|
|
function formatIso(d) {
|
|
const y = d.getFullYear()
|
|
const m = String(d.getMonth() + 1).padStart(2, '0')
|
|
const day = String(d.getDate()).padStart(2, '0')
|
|
return `${y}-${m}-${day}`
|
|
}
|
|
|
|
export function enrichCourseForDisplay(course) {
|
|
const remaining = course.capacity - course.enrolled
|
|
const percent = Math.round((course.enrolled / course.capacity) * 100)
|
|
return {
|
|
...course,
|
|
remaining,
|
|
percent,
|
|
full: remaining <= 0,
|
|
scarcityLabel: remaining > 0 && remaining <= 5 ? `仅剩${remaining}席` : ''
|
|
}
|
|
}
|
|
|
|
export { courseCatalogMock }
|