Files
mp-pilates/packages/app/src/stores/invite.ts
2026-09-09 10:10:52 +08:00

56 lines
1.9 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { InviteActivitySummary } from '@mp-pilates/shared'
import { get, post } from '../utils/request'
export const useInviteStore = defineStore('invite', () => {
const activity = ref<InviteActivitySummary | null>(null)
let activityRevision = 0
async function refreshActivity() {
const requestRevision = ++activityRevision
try {
const result = await get<InviteActivitySummary>('/invite/activity')
if (requestRevision === activityRevision) activity.value = result
} catch (err) {
if (requestRevision === activityRevision) activity.value = null
throw err
}
}
const code = ref('')
const eligible = ref(false)
const pendingCode = ref('')
let revision = 0
let confirming = false
async function refresh() {
if (confirming) return
const requestRevision = ++revision
const result = await get<{ inviteCode: string; discountEligible: boolean }>('/invite/code')
if (requestRevision !== revision) return
code.value = result.inviteCode
eligible.value = result.discountEligible
}
async function confirm(value: string) {
const requestRevision = ++revision
confirming = true
try {
const result = await post<{ inviteCode: string; discountEligible: boolean }>('/invite/confirm', { code: value })
if (requestRevision !== revision) throw new Error('登录状态已变化,请重试')
code.value = result.inviteCode
eligible.value = result.discountEligible
pendingCode.value = ''
} finally {
confirming = false
}
}
function reset() {
activityRevision++
activity.value = null
revision++
code.value = ''
eligible.value = false
pendingCode.value = ''
}
function price(value: number) { return eligible.value ? Math.round(value * 95 / 100) : value }
return { activity, refreshActivity, code, eligible, pendingCode, refresh, confirm, reset, price }
})