bindbox-mini/composables/useRewards.js

87 lines
2.7 KiB
JavaScript

/**
* 奖励数据管理 Composable
*/
import { ref, computed, watch } from 'vue'
import { getActivityIssueRewards } from '@/api/appUser'
import { normalizeRewards, groupRewardsByLevel } from '@/utils/activity'
import { cleanUrl } from '@/utils/format'
/**
* 奖励数据管理
* @param {Ref<string>} activityIdRef - 活动ID的响应式引用
* @param {Ref<string>} currentIssueIdRef - 当前期ID的响应式引用
*/
export function useRewards(activityIdRef, currentIssueIdRef) {
const rewardsMap = ref({})
const loading = ref(false)
const currentIssueRewards = computed(() => {
const issueId = currentIssueIdRef?.value || currentIssueIdRef
const m = rewardsMap.value || {}
return (issueId && Array.isArray(m[issueId])) ? m[issueId] : []
})
const rewardGroups = computed(() => {
return groupRewardsByLevel(currentIssueRewards.value)
})
/**
* 获取多期的奖励数据 (无缓存)
* @param {Array} issueList - 期列表
*/
async function fetchRewardsForIssues(issueList) {
const activityId = activityIdRef?.value || activityIdRef
if (!activityId) return
const toFetch = issueList || []
if (toFetch.length === 0) return
loading.value = true
try {
const promises = toFetch.map(it => getActivityIssueRewards(activityId, it.id))
const results = await Promise.allSettled(promises)
results.forEach((res, i) => {
const issueId = toFetch[i]?.id
if (!issueId) return
const value = res.status === 'fulfilled' ? normalizeRewards(res.value, cleanUrl) : []
rewardsMap.value = { ...rewardsMap.value, [issueId]: value }
})
} catch (e) {
console.error('fetchRewardsForIssues error', e)
} finally {
loading.value = false
}
}
/**
* 获取单期的奖励数据
* @param {string} issueId - 期ID
*/
async function fetchRewardsForIssue(issueId) {
const activityId = activityIdRef?.value || activityIdRef
if (!activityId || !issueId) return
loading.value = true
try {
const res = await getActivityIssueRewards(activityId, issueId)
const value = normalizeRewards(res, cleanUrl)
rewardsMap.value = { ...rewardsMap.value, [issueId]: value }
} catch (e) {
console.error('fetchRewardsForIssue error', e)
} finally {
loading.value = false
}
}
return {
rewardsMap,
loading,
currentIssueRewards,
rewardGroups,
fetchRewardsForIssues,
fetchRewardsForIssue
}
}