56 lines
1.9 KiB
TypeScript
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 }
|
|
})
|