Files
gym-manage/gym-manage-uniapp/common/memberInfo/moduleStore.js
T
2026-06-04 14:18:53 +08:00

271 lines
11 KiB
JavaScript

import { moduleMock } from './mockData.js'
function clone(value) {
return JSON.parse(JSON.stringify(value))
}
export function getDefaultModuleState() {
return {
trainingReport: clone(moduleMock.trainingReport),
coupons: clone(moduleMock.coupons),
couponCenter: clone(moduleMock.couponCenter),
pointsHistory: clone(moduleMock.pointsHistory),
pointsRewards: clone(moduleMock.pointsRewards),
redeemRecords: [],
referralRecords: clone(moduleMock.referralRecords),
myCourses: clone(moduleMock.myCourses),
checkInHistory: clone(moduleMock.checkInHistory)
}
}
export function mergeModuleState(saved) {
const defaults = getDefaultModuleState()
if (!saved) return defaults
return {
trainingReport: { ...defaults.trainingReport, ...(saved.trainingReport || {}) },
coupons: saved.coupons?.length ? saved.coupons : defaults.coupons,
couponCenter: saved.couponCenter?.length ? saved.couponCenter : defaults.couponCenter,
pointsHistory: saved.pointsHistory?.length ? saved.pointsHistory : defaults.pointsHistory,
pointsRewards: saved.pointsRewards?.length ? saved.pointsRewards : defaults.pointsRewards,
redeemRecords: saved.redeemRecords || defaults.redeemRecords,
referralRecords: saved.referralRecords?.length ? saved.referralRecords : defaults.referralRecords,
myCourses: saved.myCourses ? mergeMyCourses(defaults.myCourses, saved.myCourses) : defaults.myCourses,
checkInHistory: saved.checkInHistory?.length ? saved.checkInHistory : defaults.checkInHistory
}
}
function mergeMyCourses(defaults, saved) {
return {
group: saved.group || defaults.group,
private: saved.private || defaults.private,
online: saved.online?.length ? saved.online : defaults.online,
package: saved.package?.length ? saved.package : defaults.package
}
}
function syncCouponSummary(store) {
const available = store.modules.coupons.filter((c) => c.status === 'available')
const top = available[0]
store.couponPoints = {
...store.couponPoints,
amount: top ? `¥${top.amount}` : '暂无',
couponDesc: top
? `${top.minSpend}可用 · ${available.length}`
: '暂无可用优惠券',
couponAction: available.length ? '去使用' : '去领取',
points: store.stats.pointsBalance,
pointsLabel: '我的积分',
pointsAction: '去兑换'
}
return store
}
export function finalizeModules(store) {
syncCouponSummary(store)
store.checkIns = store.modules.checkInHistory.slice(0, 3).map((item) => ({ ...item }))
return store
}
export function getTrainingReportData(store, period = 'week') {
const report = store.modules.trainingReport
const trend = period === 'month' ? report.monthlyHours : report.weeklyHours
const calTrend = period === 'month' ? report.monthlyCalories : report.weeklyHours.map((w, i) => ({
label: w.label,
value: Math.round((report.summary.calories / 7) * (w.value || 0.5))
}))
return {
...report,
period,
summary: {
...report.summary,
hours: store.stats.trainingHours ?? report.summary.hours,
visits: report.summary.visits ?? store.stats.checkInCount ?? 5
},
trendHours: trend.map((t) => ({ ...t, id: t.label })),
trendCalories: calTrend.map((t) => ({ ...t, id: t.label })),
sessions: report.sessions.map((s) => ({ ...s }))
}
}
export function getTrainingSessionById(store, id) {
const session = store.modules.trainingReport.sessions.find((s) => s.id === Number(id))
if (!session) return null
return {
...session,
heartRate: '128 bpm',
comment: '动作标准,核心发力良好,下次可增加负重。',
checkInTime: `${session.date} ${session.time.split('-')[0]}`
}
}
export function filterTrainingSessions(store, filters = {}) {
let list = store.modules.trainingReport.sessions.map((s) => ({ ...s }))
if (filters.type && filters.type !== 'all') {
list = list.filter((s) => s.type === filters.type)
}
return list
}
export function getCouponsByStatus(store, status) {
return store.modules.coupons.filter((c) => c.status === status).map((c) => ({ ...c }))
}
export function getCouponById(store, id) {
const c = store.modules.coupons.find((item) => item.id === Number(id))
return c ? { ...c } : null
}
export function useCoupon(store, id) {
const coupon = store.modules.coupons.find((c) => c.id === id)
if (!coupon || coupon.status !== 'available') return null
coupon.status = 'used'
coupon.usedAt = new Date().toISOString().slice(0, 10)
syncCouponSummary(store)
return coupon
}
export function deleteExpiredCoupon(store, id) {
const idx = store.modules.coupons.findIndex((c) => c.id === id && c.status === 'expired')
if (idx >= 0) store.modules.coupons.splice(idx, 1)
syncCouponSummary(store)
return store
}
export function getCouponCenterList(store) {
return store.modules.couponCenter.map((c) => ({ ...c }))
}
export function claimCouponFromCenter(store, centerId) {
const item = store.modules.couponCenter.find((c) => c.id === centerId)
if (!item || item.claimed) return { ok: false, message: '已领取或不存在' }
const nextId = store.modules.coupons.reduce((m, c) => Math.max(m, c.id || 0), 0) + 1
const expire = new Date()
expire.setDate(expire.getDate() + item.expireDays)
store.modules.coupons.unshift({
id: nextId,
status: 'available',
amount: item.amount,
title: item.title,
desc: item.desc,
expire: expire.toISOString().slice(0, 10),
minSpend: item.minSpend,
tag: item.tag,
rules: `领取后${item.expireDays}天内有效,满${item.minSpend}可用`,
scope: '全门店',
flow: '预约课程时使用'
})
item.claimed = true
syncCouponSummary(store)
return { ok: true, message: '领取成功' }
}
export function getPointsPageData(store) {
return {
balance: store.stats.pointsBalance,
config: moduleMock.pointsConfig,
history: store.modules.pointsHistory.map((h) => ({ ...h })),
rewards: store.modules.pointsRewards.map((r) => ({ ...r })),
redeemRecords: (store.modules.redeemRecords || []).map((r) => ({ ...r }))
}
}
function nextHistoryId(history) {
return (history || []).reduce((max, item) => Math.max(max, item.id || 0), 0) + 1
}
function formatNow() {
const d = new Date()
const pad = (n) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
}
export function redeemPointsReward(store, rewardId) {
const reward = store.modules.pointsRewards.find((r) => r.id === rewardId)
if (!reward || reward.stock <= 0) return { ok: false, message: '库存不足' }
if (store.stats.pointsBalance < reward.cost) {
return { ok: false, message: '积分不足' }
}
store.stats.pointsBalance -= reward.cost
reward.stock -= 1
store.modules.pointsHistory.unshift({
id: nextHistoryId(store.modules.pointsHistory),
type: 'spend',
title: `兑换${reward.name}`,
amount: -reward.cost,
time: formatNow(),
balance: store.stats.pointsBalance
})
store.modules.redeemRecords = store.modules.redeemRecords || []
store.modules.redeemRecords.unshift({
id: nextHistoryId(store.modules.redeemRecords),
name: reward.name,
cost: reward.cost,
time: formatNow()
})
syncCouponSummary(store)
return { ok: true, message: '兑换成功', reward }
}
export function filterPointsHistory(store, filter = 'all') {
const list = store.modules.pointsHistory
if (filter === 'earn') return list.filter((h) => h.amount > 0).map((h) => ({ ...h }))
if (filter === 'spend') return list.filter((h) => h.amount < 0).map((h) => ({ ...h }))
return list.map((h) => ({ ...h }))
}
export function getReferralPageData(store) {
return {
...store.referral,
records: store.modules.referralRecords.map((r) => ({ ...r })),
rules: moduleMock.referralRules,
rewardSummary: moduleMock.referralRewardSummary
}
}
export function getMyCoursesData(store, tab) {
const data = store.modules.myCourses
if (tab === 'group') return { ...data.group }
if (tab === 'private') return { ...data.private }
if (tab === 'online') return { list: data.online.map((c) => ({ ...c })) }
if (tab === 'package') return { list: data.package.map((c) => ({ ...c })) }
return {}
}
export function getOnlineCourseById(store, id) {
const course = store.modules.myCourses.online.find((c) => c.id === Number(id))
if (!course) return null
return {
...course,
chapters: [
{ id: 1, title: '热身激活', duration: '8分钟', done: true },
{ id: 2, title: '核心训练 A', duration: '12分钟', done: true },
{ id: 3, title: '核心训练 B', duration: '10分钟', done: true },
{ id: 4, title: '拉伸放松', duration: '8分钟', done: true },
{ id: 5, title: '进阶组合', duration: '15分钟', done: false },
{ id: 6, title: '总结复盘', duration: '5分钟', done: false }
],
comments: [{ user: '学员A', text: '跟着练很方便' }]
}
}
export function updateOnlineProgress(store, courseId, progress) {
const course = store.modules.myCourses.online.find((c) => c.id === Number(courseId))
if (course) course.progress = progress
return course
}
export function getCheckInHistory(store, filter = 'all') {
const list = store.modules.checkInHistory
if (filter === 'all') return list.map((i) => ({ ...i }))
return list.filter((i) => i.tagTheme === filter).map((i) => ({ ...i }))
}
/** @deprecated use getMyCoursesData */
export function getMyCoursesByTab(store, tab) {
if (tab === 'ongoing') return store.modules.myCourses.group?.ongoing || []
if (tab === 'completed') return store.modules.myCourses.group?.completed || []
return []
}
export { moduleMock }