diff --git a/src/api/weeklyStar.js b/src/api/weeklyStar.js new file mode 100644 index 0000000..1d7e281 --- /dev/null +++ b/src/api/weeklyStar.js @@ -0,0 +1,105 @@ +import { get, post } from '../utils/http.js' + +// 获取礼物榜单 +export const getWeekStarRanking = async (data) => { + try { + const response = await get( + `/activity/week-star/ranking?type=${data.type}¤t=${data.current}&size=${data.size}` + ) + return response + } catch (error) { + console.error('Failed to get week star ranking:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取我的排名 +export const getMyWeekStarRanking = async (type) => { + try { + const response = await get(`/activity/week-star/my-rank?type=${type}`) + return response + } catch (error) { + console.error('Failed to get my week star ranking:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取本周奖励 +export const getWeekRewards = async () => { + try { + const response = await get(`/activity/week-star/reward`) + return response + } catch (error) { + console.error('Failed to get this week rewards:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取本周礼物 +export const getWeekGifts = async (type) => { + try { + const response = await get(`/activity/week-star/gifts?type=${type}`) + return response + } catch (error) { + console.error('Failed to get this week gifts:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取历史周星top1 +export const getHistoryTopOne = async () => { + try { + const response = await get(`/activity/week-star/history-top1`) + return response + } catch (error) { + console.error('Failed to get history top one:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取本周可兑换商品 +export const getExchangeGoods = async (data) => { + try { + const response = await get( + `/props-activity-cnf/client/listActivityResource?sysOrigin=${data.sysOrigin}&activityType=${data.activityType}` + ) + return response + } catch (error) { + console.error('Failed to get exchange goods:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取我拥有的碎片 +export const getMyFragment = async (data) => { + try { + const response = await post( + `/user/backpack/client/list/by/user-id?userId=${data.userId}&fragmentsIds=${data.fragmentsIds}` + ) + return response + } catch (error) { + console.error('Failed to get my fragment:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取我拥有的碎片 +export const exchangeGood = async (data) => { + try { + const response = await post( + `/activity/week-star/exchange?propsGroupId=${data.propsGroupId}&fragmentsId=${data.fragmentsId}` + ) + return response + } catch (error) { + console.error('Failed to exchange goods:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} diff --git a/src/assets/images/WeeklyStar/ConfirmBt.png b/src/assets/images/WeeklyStar/ConfirmBt.png new file mode 100644 index 0000000..ed48047 Binary files /dev/null and b/src/assets/images/WeeklyStar/ConfirmBt.png differ diff --git a/src/assets/images/WeeklyStar/RankingMain.png b/src/assets/images/WeeklyStar/RankingMain.png index 10f9981..550903f 100644 Binary files a/src/assets/images/WeeklyStar/RankingMain.png and b/src/assets/images/WeeklyStar/RankingMain.png differ diff --git a/src/assets/images/WeeklyStar/RedeemBt.png b/src/assets/images/WeeklyStar/RedeemBt.png new file mode 100644 index 0000000..824fe66 Binary files /dev/null and b/src/assets/images/WeeklyStar/RedeemBt.png differ diff --git a/src/assets/images/WeeklyStar/btBg.png b/src/assets/images/WeeklyStar/btBg.png new file mode 100644 index 0000000..4da3ef5 Binary files /dev/null and b/src/assets/images/WeeklyStar/btBg.png differ diff --git a/src/assets/images/WeeklyStar/debris.png b/src/assets/images/WeeklyStar/debris.png new file mode 100644 index 0000000..a589842 Binary files /dev/null and b/src/assets/images/WeeklyStar/debris.png differ diff --git a/src/assets/images/WeeklyStar/giftsBg.png b/src/assets/images/WeeklyStar/giftsBg.png index 29ec4c6..4faabb0 100644 Binary files a/src/assets/images/WeeklyStar/giftsBg.png and b/src/assets/images/WeeklyStar/giftsBg.png differ diff --git a/src/assets/images/WeeklyStar/helpInfo.png b/src/assets/images/WeeklyStar/helpInfo.png new file mode 100644 index 0000000..6abb09a Binary files /dev/null and b/src/assets/images/WeeklyStar/helpInfo.png differ diff --git a/src/assets/images/WeeklyStar/longBg.png b/src/assets/images/WeeklyStar/longBg.png new file mode 100644 index 0000000..5db761c Binary files /dev/null and b/src/assets/images/WeeklyStar/longBg.png differ diff --git a/src/assets/images/WeeklyStar/mediumBg.png b/src/assets/images/WeeklyStar/mediumBg.png new file mode 100644 index 0000000..bfd1c1a Binary files /dev/null and b/src/assets/images/WeeklyStar/mediumBg.png differ diff --git a/src/assets/images/WeeklyStar/nameBg.png b/src/assets/images/WeeklyStar/nameBg.png new file mode 100644 index 0000000..8b9bcfd Binary files /dev/null and b/src/assets/images/WeeklyStar/nameBg.png differ diff --git a/src/assets/images/WeeklyStar/topBg.png b/src/assets/images/WeeklyStar/topBg.png index 9672904..7c3ab30 100644 Binary files a/src/assets/images/WeeklyStar/topBg.png and b/src/assets/images/WeeklyStar/topBg.png differ diff --git a/src/assets/images/WeeklyStar/topOneHistory.png b/src/assets/images/WeeklyStar/topOneHistory.png new file mode 100644 index 0000000..b67a9d7 Binary files /dev/null and b/src/assets/images/WeeklyStar/topOneHistory.png differ diff --git a/src/components/WeeklyStar/topUser.vue b/src/components/WeeklyStar/topUser.vue index 00b41ed..5b91ed8 100644 --- a/src/components/WeeklyStar/topUser.vue +++ b/src/components/WeeklyStar/topUser.vue @@ -27,13 +27,41 @@ alt="" width="100%" style="border-radius: 50%; aspect-ratio: 1/1; object-fit: cover" + @error="defaultAvatarUrl" /> -
-
{{ name }}
-
{{ distributionValue }}
+
+
+
+ {{ name }} +
+
+
+
+ {{ distributionValue }} +
+
@@ -66,6 +94,11 @@ const props = defineProps({ default: '', }, }) + +const defaultAvatarUrl = (e) => { + console.log('头像资源出错') + e.target.src = '/src/assets/images/WeeklyStar/defaultAvatar.png' +} diff --git a/src/views/WeeklyStar/WeeklyStar.vue b/src/views/WeeklyStar/WeeklyStar.vue index c8aa9e8..6c650e1 100644 --- a/src/views/WeeklyStar/WeeklyStar.vue +++ b/src/views/WeeklyStar/WeeklyStar.vue @@ -1,270 +1,179 @@ @@ -472,14 +819,29 @@ import { computed, onMounted, onUnmounted, ref } from 'vue' import itemCenter from '@/components/WeeklyStar/itemCenter.vue' import TopUser from '@/components/WeeklyStar/topUser.vue' import maskLayer from '../../components/MaskLayer.vue' +import { useDebounce, useThrottle } from '@/utils/useDebounce' +import { getUserId } from '@/utils/userStore.js' +import { showError, showWarning, showInfo, showSuccess } from '@/utils/toast.js' +import { + getWeekStarRanking, + getWeekRewards, + getWeekGifts, + getHistoryTopOne, + getMyWeekStarRanking, + getMyFragment, + getExchangeGoods, + exchangeGood, +} from '@/api/weeklyStar.js' const isInAppEnvironment = ref(false) // 检测是否在APP环境中 const helpInfoShow = ref(false) //帮助模块 const historyShow = ref(false) //历史模块 const giftsShow = ref(false) //礼物模块 +const exchargeGoodsShow = ref(false) //交易弹窗 +// 展示遮罩层 const maskLayerShow = computed(() => { - return helpInfoShow.value || historyShow.value || giftsShow.value + return helpInfoShow.value || historyShow.value || giftsShow.value || exchargeGoodsShow.value }) // 倒计时 @@ -489,46 +851,110 @@ const Minutes = ref(0) const Second = ref(0) let timer = null -const rankingShow = ref(true) -const rewardShow = ref(false) -const exchargeShow = ref(false) +// 模块切换展示 +const rankingShow = ref(true) //排行榜 +const rewardShow = ref(false) //奖励 +const exchargeShow = ref(false) //交易 -// 排行榜 -const Ranking = ref( - Array.from({ length: 5 }, () => ({ - rank: 111, - userNickname: 'aaaaaaaaaaaaaa', - account: '8826602', - quantity: '111', - })) -) +const current = ref(1) //排行榜第几页 +const RankingLoadmore = ref(null) //触底模块 +const showRankingLoading = ref(true) //触底加载功能 +const Ranking = ref([]) // 排行榜 + +const RankingLoadParams = computed(() => { + return { + type: 'THIS_WEEK', + current: current.value, + size: 10, + } +}) + +const myRanking = ref([]) // 我的排名 +const rewardsList = ref([]) // 奖励列表 +const gifts = ref([]) // 本周礼物 + +const historyRankingTop1 = ref([]) // 历史榜首 +const historyIndex = ref(0) +const showTopOne = computed(() => { + return historyRankingTop1.value[historyIndex.value] +}) + +const exchangeGoodsList = ref([]) +const myFragment = ref({}) +const selectedGood = ref({}) + +const changeHistoryIndex = (num) => { + let targetIndex = historyIndex.value + num + let length = historyRankingTop1.value.length + if (targetIndex >= 0 && targetIndex < length) { + historyIndex.value = targetIndex + } +} + +// 处理排行榜小于3人时的情况 +const RankingHasTop3 = computed(() => { + let RankingShow = [...Ranking.value] + if (Ranking.value.length < 3) { + let addNullUser = Array.from({ length: 3 - Ranking.value.length }, () => ({ + userAvatar: '', + userNickname: '', + quantity: '', + })) + RankingShow.push(...addNullUser) + } + return RankingShow +}) // 展示用的榜单 const showRanking = computed(() => { return Ranking.value.filter((_, index) => index >= 3) }) -// 本周礼物 -const gifts = ref( - Array.from({ length: 3 }, () => ({ - quantity: '111', - })) -) +// 图片资源出错处理 +const handleImageError = (e, type) => { + console.log('图片资源出错') + e.target.onerror = null + if ((type = 'GOLD')) { + e.target.src = '/src/assets/icon/coin.png' + } +} -// 奖励列表 -const rewardsList = ref( - Array.from({ length: 3 }, () => - Array.from({ length: 4 }, () => ({ - userNickname: 'aaa', - })) - ) -) +const defaultAvatarUrl = (e) => { + console.log('头像资源出错') + e.target.src = '/src/assets/images/WeeklyStar/defaultAvatar.png' +} + +// 选中要兑换的商品 +const selectGood = (good) => { + exchargeGoodsShow.value = true + selectedGood.value = good +} + +const exchangeSelectedGood = async (propsGroupId) => { + try { + let data = { + propsGroupId, + fragmentsId: '1968948330210508801', + } + const resExchangeGood = await exchangeGood(data) + + if (resExchangeGood.status) { + getThisWeekExchangeGoods() //刷新我的碎片 + } + } catch (error) { + console.log('error:', error) + // 信息提示id有误 + showWarning(error.response.errorMsg) + } +} // 关闭弹窗 const closedPopup = () => { helpInfoShow.value = false historyShow.value = false giftsShow.value = false + exchargeGoodsShow.value = false + selectedGood.value = {} //选中商品置空 } // 点击展示主体内容 @@ -538,22 +964,21 @@ const handleBt = (type) => { exchargeShow.value = type == 'Exchange' ? true : false } -// 获取下周的时间戳 -const getNextMonday = () => { - const now = new Date() //当前时间 - const day = now.getDay() //0周日6周六 +// 获取沙特下周一早上六点的时间戳 +const getNextMondayInSaudi = () => { + const now = new Date() + const utcDay = now.getUTCDay() //获取UTC星期几,0(周日)-6(周六) - // 计算到下周的所需天数 - const dayToAdd = day === 1 ? 7 : (7 + 1 - day) % 7 - const nextMonday = new Date(now) //以当前时间为基准,而不是重新获取时间 + // 计算到下周一的所需天数 + const daysToAdd = utcDay === 1 ? 7 : (1 + 7 - utcDay) % 7 + const nextMondayUTC = new Date(now) //以当前UTC时间为基准,而不是重新获取 - nextMonday.setDate(now.getDate() + dayToAdd) //增加到下周一那天 - nextMonday.setHours(0, 0, 0, 0) - - return nextMonday.getTime() //得到下周一00:00:00.000的时间戳 + nextMondayUTC.setUTCDate(now.getUTCDate() + daysToAdd) //增加到下周一那天 + nextMondayUTC.setUTCHours(3, 0, 0, 0) // 设置为沙特下周一当天早上6点(北京时间3点) + return nextMondayUTC.getTime() //得到下周一00:00:00.000的时间戳 } -const targetTime = ref(getNextMonday()) // 闭包保存目标时间 (核心修正) +const targetTime = ref(getNextMondayInSaudi()) // 闭包保存目标时间 (核心修正) // 格式化时间 const formatTime = (value) => { @@ -566,6 +991,8 @@ const getCountdown = () => { let diff = targetTime.value - now if (diff <= 0) { + // 初始化数据 + resetPage() targetTime.value += 7 * 86400000 // +7天 (更新闭包变量) diff = targetTime.value - now } @@ -577,12 +1004,147 @@ const getCountdown = () => { Second.value = formatTime(Math.floor(totalSeconds % 60)) } +// 重置数据 +const resetPage = () => { + current.value = 1 //排行榜第几页 + showRankingLoading.value = true //触底加载功能 + Ranking.value = [] // 排行榜 + + historyIndex.value = 0 //历史榜首重置展示当前 + + updatePageData() // 刷新页面数据 +} + +// 格式化奖励的展示信息 +const showDetail = (type, quantity) => { + let showamount = ['GOLD', 'DIAMOND', 'GIFT', 'FRAGMENTS'] + if (showamount.includes(type)) { + return quantity + } else { + return `${quantity}Days` + } +} + +// 获取本周排名 +const getThisWeekRanking = async () => { + const resWeekStarRanking = await getWeekStarRanking(RankingLoadParams.value) + console.log('resWeekStarRanking:', resWeekStarRanking) + if ( + resWeekStarRanking.status && + resWeekStarRanking.body && + resWeekStarRanking.body.rankUsers.records + ) { + let rankUsers = resWeekStarRanking.body.rankUsers + Ranking.value.push(...rankUsers.records) + if (current.value * rankUsers.size >= rankUsers.total) { + showRankingLoading.value = false + } + } +} + +// 获取历史榜首 +const getHistoryRankingTop1 = async () => { + const resHistoryTopOne = await getHistoryTopOne() + console.log('resHistoryTopOne:', resHistoryTopOne) + if (resHistoryTopOne.status && resHistoryTopOne.body) { + historyRankingTop1.value = resHistoryTopOne.body + } +} + +// 获取本周我的排名 +const getMyThisWeekRanking = async () => { + const resMyWeekStarRanking = await getMyWeekStarRanking('THIS_WEEK') + console.log('resMyWeekStarRanking:', resMyWeekStarRanking) + if (resMyWeekStarRanking.status && resMyWeekStarRanking.body) { + myRanking.value = resMyWeekStarRanking.body + } +} + +// 获取本周礼物 +const getThisWeekGifts = async () => { + const resThisWeekGifts = await getWeekGifts('THIS_WEEK') + console.log('resThisWeekGifts:', resThisWeekGifts) + if (resThisWeekGifts.status && resThisWeekGifts.body) { + gifts.value = resThisWeekGifts.body + } +} + +// 获取本周奖励 +const getThisWeekRewards = async () => { + const resThisWeekRewards = await getWeekRewards() + console.log('resThisWeekRewards:', resThisWeekRewards) + if (resThisWeekRewards.status && resThisWeekRewards.body) { + rewardsList.value = resThisWeekRewards.body + } +} + +// 获取本周可兑换商品 +const getThisWeekExchangeGoods = async () => { + let data = { + sysOrigin: 'LIKEI', + activityType: 'STAR_EXCHANGE', + } + const resExchangeGoods = await getExchangeGoods(data) + console.log('resExchangeGoods:', resExchangeGoods) + if (resExchangeGoods.status && resExchangeGoods.body) { + exchangeGoodsList.value = resExchangeGoods.body + } +} + +// 获取本周我拥有的碎片 +const getThisWeekMyFragment = async () => { + let data = { + userId: getUserId(), + fragmentsIds: ['1968948330210508801'], + } + + const resMyFragment = await getMyFragment(data) + console.log('resMyFragment:', resMyFragment) + if (resMyFragment.status && resMyFragment.body) { + myFragment.value = + resMyFragment.body.find((item) => item.fragmentsId == '1968948330210508801') || {} + } +} + +// 刷新页面数据 +const updatePageData = () => { + getThisWeekRanking() // 获取本周排名 + getHistoryRankingTop1() // 获取历史top1 + getMyThisWeekRanking() // 获取本周我的排名 + getThisWeekRewards() // 获取本周奖励 + getThisWeekGifts() // 获取本周礼物 + getThisWeekExchangeGoods() // 获取本周可兑换商品 + getThisWeekMyFragment() // 获取本周我的碎片 +} + +const debouceGetThisWeekRanking = useThrottle(() => { + getThisWeekRanking() +}, 1000) + +// IntersectionObserver配置 +const observer = new IntersectionObserver((entries) => { + entries.forEach((entry) => { + if (entry.intersectionRatio > 0 && Ranking.value.length != 0) { + console.log('触发RankingLoadmore加载') + current.value++ + debouceGetThisWeekRanking() + } + }) +}) + // 组件挂载时检测环境 onMounted(() => { isInAppEnvironment.value = isInApp() getCountdown() timer = setInterval(getCountdown, 1000) //每秒更新 + + updatePageData() // 刷新页面数据 + + // 监听加载模块 + if (RankingLoadmore.value) { + observer.observe(RankingLoadmore.value) + } }) onUnmounted(() => { @@ -592,19 +1154,14 @@ onUnmounted(() => {