From caef58fa1585f42284f58023b29dc795de8bda67 Mon Sep 17 00:00:00 2001 From: hzj <1304805162@qq.com> Date: Wed, 22 Oct 2025 19:39:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=8A=BD=E5=A5=96=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E9=A1=B5):=20=E5=AF=B9=E6=8E=A5=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/lottery.js | 106 ++++++++ src/views/Activities/Lottery/Lottery.vue | 297 +++++++++++++++++------ 2 files changed, 332 insertions(+), 71 deletions(-) create mode 100644 src/api/lottery.js diff --git a/src/api/lottery.js b/src/api/lottery.js new file mode 100644 index 0000000..1fb4d35 --- /dev/null +++ b/src/api/lottery.js @@ -0,0 +1,106 @@ +import { get, post } from '../utils/http.js' + +// 获取排行榜 +export const ranklist = async (applicationId) => { + try { + const response = await get(`/activity/lottery/rank-list`) + return response + } catch (error) { + console.error('Failed to fetch get rank list:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取有效活动 +export const validActivity = async () => { + try { + const response = await get(`/activity/lottery/valid-activity`) + return response + } catch (error) { + console.error('Failed to fetch get valid activity:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取活动详情 +export const activityDetail = async (activityCode) => { + try { + const response = await get(`/activity/lottery/detail/${activityCode}`) + return response + } catch (error) { + console.error('Failed to fetch get activity detail:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取剩余中奖券 +export const myTickets = async () => { + try { + const response = await get(`/activity/lottery/my-ticket-count`) + return response + } catch (error) { + console.error('Failed to fetch get my tickets:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 执行单次抽奖 +export const onceDraw = async (data) => { + try { + const response = await post('/activity/lottery/draw', data) + return response + } catch (error) { + console.error('Failed to fetch once draw:', error) + throw error + } +} + +// 执行连抽 +export const multiDraw = async (data) => { + try { + const response = await post('/activity/lottery/multi-draw', data) + return response + } catch (error) { + console.error('Failed to fetch multiply draw:', error) + throw error + } +} + +// 获取中奖记录 +export const drawRecords = async () => { + try { + const response = await get(`/activity/lottery/my-records`) + return response + } catch (error) { + console.error('Failed to fetch get draw records:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 获取任务列表 +export const ActTaskList = async () => { + try { + const response = await get(`/spins/task/list`) + return response + } catch (error) { + console.error('Failed to fetch get tickets:', error) + console.error('error:' + error.response.errorMsg) + throw error + } +} + +// 领取任务奖励 +export const receiveTickets = async (data) => { + try { + const response = await post('/spins/task/receive/reward', data) + return response + } catch (error) { + console.error('Failed to fetch receive reward:', error) + throw error + } +} diff --git a/src/views/Activities/Lottery/Lottery.vue b/src/views/Activities/Lottery/Lottery.vue index 703c7a2..0c43afb 100644 --- a/src/views/Activities/Lottery/Lottery.vue +++ b/src/views/Activities/Lottery/Lottery.vue @@ -43,7 +43,7 @@ >
Ranking
-
999
+
{{ user.rank }}
- asdfadsfasfasfda + {{ user.nickname || '' }}
- -
99999
+ +
{{ user.totalAmount }}
@@ -100,7 +104,7 @@ @click="helpShow = true" /> - Nanfangjianasdfasdfasdfasdf + {{ userInfo.userNickname || '' }}
Current amount:$1
@@ -152,6 +156,7 @@
Transfer To Recharge Agent
- -
{{ prize.value }}
+ +
{{ prize.prizeName }}
@@ -515,21 +520,21 @@
-
{{ task.title }}
+
+
+ {{ showTarget(task) }} +
+
+ {{ task.taskName }} +
+
-
*1
+
*{{ task.rewardValue }}
+ + +
@@ -591,22 +607,26 @@ " >
-
999
+
{{ userInfo.rank || 999 }}
- asdfadsfasfasfda + {{ userInfo.userNickname || '' }}
- -
99999
+ +
{{ userInfo.totalAmount || 0 }}
@@ -650,7 +670,12 @@ /> - +
- You Get {{ result[resultShowIndex]?.value }} + You Get {{ result[resultShowIndex]?.prize?.prizeName }}
-
100000 coins
-
x1
+
+ {{ record.prize.prizeName }} x1 +
+
+
+ {{ formatUTCCustom(record.drawTime) }}
-
2025.08.01 10:59:59
@@ -801,8 +829,20 @@ import { import { computed, nextTick, onMounted, onUnmounted, ref } from 'vue' import maskLayer from '@/components/MaskLayer.vue' import { useDebounce, useThrottle } from '@/utils/useDebounce' -import { getMemberProfile } from '@/api/wallet' +import { formatUTCCustom } from '@/utils/utcFormat.js' +import { getMemberProfile, getUserIdentity } from '@/api/wallet' import { useRouter } from 'vue-router' +import { + ranklist, //获取排行榜 + validActivity, // 获取有效活动 + activityDetail, // 获取活动详情 + myTickets, // 获取剩余中奖券 + onceDraw, // 执行单次抽奖 + multiDraw, // 执行连抽 + drawRecords, // 获取中奖记录 + ActTaskList, // 获取任务列表 + receiveTickets, // 领取任务奖励 +} from '@/api/lottery' import Barrage from '@/components/Lottery/Barrage.vue' const router = useRouter() @@ -825,23 +865,23 @@ const barrageList = ref([ { text: 'Junge withdrew $10', type: 'doller' }, ]) +// 活动详情 +const activity = ref({}) + // 奖品数据 (8个位置) -const prizes = ref([ - { value: '奖品1' }, - { value: '奖品2' }, - { value: '奖品3' }, - { value: '奖品4' }, - { value: '奖品5' }, - { value: '奖品6' }, - { value: '奖品7' }, - { value: '奖品8' }, -]) +const prizes = ref([]) + +const userInfo = ref({}) //用户信息 +const userIdentity = ref({}) //用户身份 + +const ranking = ref([]) //奖品排名 const activeIndex = ref(-1) // 当前高亮格子 const isRolling = ref(false) // 抽奖状态 -const rollTimes = ref(11) // 当前可抽奖次数 +const rollTimes = ref(0) // 当前可抽奖次数 const result = ref([]) // 抽奖结果 const resultShowIndex = ref(0) +const myRecords = ref([]) // 抽奖结果 const isInAppEnvironment = ref(false) // 检测是否在APP环境中 @@ -882,18 +922,17 @@ const handleBt = (type) => { selectedCoin.value = null // 清除选择币种 } -const taskList = ref([ - { type: 'talk', title: 'On the mic(0/15mins)', done: 1, received: 1, num: 1 }, - { type: 'talk', title: 'On the mic(0/30mins)', done: 1, received: 0, num: 1 }, - { type: 'talk', title: 'On the mic(0/1hours)', done: 0, received: 0, num: 1 }, - { type: 'talk', title: 'On the mic(0/2hours)', done: 0, received: 0, num: 1 }, - { type: 'gift', title: 'Send a gift', done: 1, received: 1, num: 1 }, - { type: 'gift', title: 'Send three gifts', done: 0, received: 0, num: 1 }, - { type: 'gift', title: 'Send ten gifts', done: 0, received: 0, num: 1 }, - { type: 'gift', title: 'Send fifteen gifts', done: 0, received: 0, num: 1 }, - { type: 'invite', title: 'Invite a user', done: 1, received: 1, num: 1 }, - { type: 'invite', title: 'Invite three users', done: 0, received: 0, num: 1 }, -]) +const taskList = ref([]) + +// 展示任务目标 +const showTarget = (task) => { + let timeType = task.targetValue < 60 + let currentValue = timeType ? task.currentValue : task.currentValue / 60 + let targetValue = timeType ? task.targetValue : task.targetValue / 60 + let timeUnit = timeType ? 'mins' : 'hours' + + return `On the mic(${currentValue}/${targetValue}${timeUnit})` +} // 选中的收款人 const selectedPayee = ref({ @@ -928,6 +967,7 @@ const selectCoin = (coin) => { } } +// 转账 const transfer = async () => { if (!selectedCoin.value) { showError('Please select an amount first') @@ -986,6 +1026,7 @@ const transfer = async () => { } } +// 关闭弹窗 const closedPopup = () => { resultShow.value = false helpShow.value = false @@ -994,12 +1035,14 @@ const closedPopup = () => { resultShowIndex.value = 0 } +// 出错头像 const defaultAvatarUrl = (e) => { console.log('头像资源出错') e.target.onerror = null //防止循环 e.target.src = new URL('/src/assets/images/WeeklyStar/defaultAvatar.png', import.meta.url).href } +//奖盘布局 const getGridPosition = (index) => { //顺时针位置 const positions = [ @@ -1015,11 +1058,9 @@ const getGridPosition = (index) => { return positions[index] } -// 抽奖 +// 抽奖动画 const startLottery = (resultIndex) => { return new Promise((resolve) => { - if (isRolling.value) return // 防止重复点击 - isRolling.value = true activeIndex.value = -1 let speed = 200 // 初始速度 @@ -1031,8 +1072,6 @@ const startLottery = (resultIndex) => { activeIndex.value = (activeIndex.value + 1) % prizes.value.length if (activeIndex.value === resultIndex && speed > 200) { - isRolling.value = false - setTimeout(() => { resolve() // 抽奖结束 }, 500) @@ -1063,18 +1102,61 @@ const startLottery = (resultIndex) => { // 连抽 const sweepstakes = async (consecutive) => { + if (isRolling.value) return // 防止重复点击 // 检查抽奖次数 if (rollTimes.value >= consecutive) { - // 抽奖次数 - for (let i = 0; i < consecutive; i++) { - const item = { value: `奖品${Math.floor(Math.random() * 8) + 1}` } //接口获取的抽奖结果 - const index = prizes.value.findIndex((prizes) => prizes.value === item.value) //转盘第几位停下 - console.log('index:', index) - await startLottery(index) - result.value.push(item) + isRolling.value = true + let data = { + activityId: activity.value.activity.id, + drawCount: consecutive, } - rollTimes.value -= consecutive + // 单抽 + if (consecutive == 1) { + const resOnceDraw = await onceDraw(data) + if (resOnceDraw.status && resOnceDraw.body) { + const resItem = resOnceDraw.body //接口获取的抽奖结果 + const index = activity.value.prizeList.findIndex( + (prize) => prize.prizeName == resItem?.prize.prizeName + ) //转盘第几位停下 + console.log('index:', index) + await startLottery(index) + result.value.push(resItem) + } + } + //连抽 + else { + const resMultiDraw = await multiDraw(data) + if (resMultiDraw.status && resMultiDraw.body) { + const resDrawList = resMultiDraw.body //连抽获取的抽奖列表结果 + for (let i = 0; i < resDrawList.results.length; i++) { + const resItem = resDrawList.results[i] + const index = activity.value.prizeList.findIndex( + (prize) => prize.prizeName == resItem?.prize.prizeName + ) //转盘第几位停下 + console.log('index:', index) + await startLottery(index) + result.value.push(resItem) + } + } + } + getTickets() //重新获取拥有的抽奖券 resultShow.value = true + isRolling.value = false + } +} + +//获取用户信息 +const getUserInfo = async () => { + if (Object.keys(userInfo.value).length === 0) { + const resUserInfo = await getMemberProfile() + if (resUserInfo.status && resUserInfo.body) { + userInfo.value = + userInfo.value == {} ? resUserInfo.body : Object.assign(userInfo.value, resUserInfo.body) + } + } + const resIdentity = await getUserIdentity() + if (resIdentity.status && resIdentity.body) { + userIdentity.value = resIdentity.body } } @@ -1093,7 +1175,7 @@ const connectToApp = async () => { console.groupEnd() // 触发连接成功回调 - // getUserInfo() + getUserInfo() return { success: true, environment: 'browser' } } @@ -1113,7 +1195,7 @@ const connectToApp = async () => { console.groupEnd() // 触发连接成功回调 - // getUserInfo() + getUserInfo() return { success: true, environment: 'app', fromCache: true } } @@ -1127,7 +1209,7 @@ const connectToApp = async () => { console.groupEnd() // 触发连接成功回调 - // getUserInfo() + getUserInfo() return { success: true, environment: 'app', fromCache: true } } @@ -1178,7 +1260,7 @@ const connectToApp = async () => { console.groupEnd() // 触发连接成功回调 - // getUserInfo() + getUserInfo() return connectionResult } catch (error) { @@ -1200,9 +1282,82 @@ const connectToApp = async () => { } } +//获取排行榜 +const getRanking = async () => { + const resRanking = await ranklist() + if (resRanking.status && resRanking.body) { + ranking.value = resRanking.body + // 在排行榜中查我的信息 + const myInfo = ranking.value.find((item) => item.account === userInfo.value.account) + if (myInfo) { + userInfo.value = userInfo.value == {} ? myInfo : Object.assign(userInfo.value, myInfo) + } + } else { + ranking.value = {} + } +} + +//获取奖池 +const getActivityDetail = async () => { + const resvalidActivity = await validActivity() //活动是否有效 + console.log('id:', resvalidActivity.body?.id) + console.log('id2:', JSON.stringify(resvalidActivity.body)) + + if (resvalidActivity.body?.activityCode) { + const resDetail = await activityDetail(resvalidActivity.body?.activityCode) + if (resDetail.status && resDetail.body) { + activity.value = resDetail.body + } else { + activity.value = {} + } + } +} + +//获取拥有的抽奖券 +const getTickets = async () => { + const resTickets = await myTickets() + if (resTickets.status && resTickets.body) { + rollTimes.value = resTickets.body + } else { + rollTimes.value = 0 + } +} + +//获取任务列表 +const getTaskList = async () => { + const resTaskList = await ActTaskList() + if (resTaskList.status && resTaskList.body) { + taskList.value = resTaskList.body + } +} + +//获取中奖记录 +const getDrawRecords = async () => { + const resDrawRecords = await drawRecords() + if (resDrawRecords.status && resDrawRecords.body) { + myRecords.value = resDrawRecords.body?.records || [] + } +} + +//获取中奖记录 +const receiveTaskReward = async (code) => { + let data = { + taskCode: code, + } + const resReceive = await receiveTickets(data) + if (resReceive.status && resReceive.body) { + getTaskList() //获取任务列表 + } +} + onMounted(() => { connectToApp() isInAppEnvironment.value = isInApp() + getRanking() //获取排行榜 + getActivityDetail() //获取奖池 + getDrawRecords() // 获取中奖记录 + getTickets() //获取拥有的抽奖券 + getTaskList() //获取任务列表 })