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() //获取任务列表
})