diff --git a/components/activity/DrawLoadingPopup.vue b/components/activity/DrawLoadingPopup.vue
new file mode 100644
index 0000000..b486a71
--- /dev/null
+++ b/components/activity/DrawLoadingPopup.vue
@@ -0,0 +1,319 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ✨
+ ⭐
+ ✨
+ 💫
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ progress }} / {{ total }}
+
+
+
+ 请稍候,好运即将到来...
+
+
+
+
+
+
+
diff --git a/composables/useRecords.js b/composables/useRecords.js
index 1ac2f13..0762fff 100644
--- a/composables/useRecords.js
+++ b/composables/useRecords.js
@@ -3,6 +3,7 @@
*/
import { ref } from 'vue'
import { getIssueDrawLogs } from '@/api/appUser'
+import { levelToAlpha } from '@/utils/activity'
/**
* 购买记录管理
@@ -55,9 +56,8 @@ export function useRecords() {
function getLevelName(level) {
if (!level) return ''
- // 尝试映射 1->A, 2->B ...
- const map = { 1: 'A', 2: 'B', 3: 'C', 4: 'D', 5: 'E', 6: 'F', 7: 'G', 8: 'H', 9: 'I', 10: 'J' }
- return map[level] || (level + '赏')
+ const alpha = levelToAlpha(level)
+ return alpha + '赏'
}
function clearRecords() {
diff --git a/pages/activity/duiduipeng/index.vue b/pages/activity/duiduipeng/index.vue
index 47a393e..ff2272c 100644
--- a/pages/activity/duiduipeng/index.vue
+++ b/pages/activity/duiduipeng/index.vue
@@ -187,6 +187,7 @@ import RecordsList from '@/components/activity/RecordsList.vue'
import RulesPopup from '@/components/activity/RulesPopup.vue'
import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
import { getActivityDetail, getActivityIssues, getActivityIssueRewards, getUserCoupons, getItemCards, createWechatOrder, getMatchingCardTypes, createMatchingPreorder, checkMatchingGame, getIssueDrawLogs, getMatchingGameCards } from '../../../api/appUser'
+import { levelToAlpha } from '@/utils/activity'
const detail = ref({})
const statusText = ref('')
@@ -634,13 +635,6 @@ function formatPercent(v) {
return `${n}%`
}
-function levelToAlpha(level) {
- if (level === 'BOSS') return 'BOSS'
- const n = Number(level)
- if (isNaN(n) || n <= 0) return String(level || '赏')
- // 1 -> A, 2 -> B ... 26 -> Z
- return String.fromCharCode(64 + n)
-}
function openRewardsPopup() {
rewardsVisible.value = true
diff --git a/pages/activity/wuxianshang/index.vue b/pages/activity/wuxianshang/index.vue
index 40b7d8e..1d786c2 100644
--- a/pages/activity/wuxianshang/index.vue
+++ b/pages/activity/wuxianshang/index.vue
@@ -103,6 +103,13 @@
v-model:visible="cabinetVisible"
:activity-id="activityId"
/>
+
+
+
@@ -120,6 +127,7 @@ import RecordsList from '@/components/activity/RecordsList.vue'
import RulesPopup from '@/components/activity/RulesPopup.vue'
import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
import LotteryResultPopup from '@/components/activity/LotteryResultPopup.vue'
+import DrawLoadingPopup from '@/components/activity/DrawLoadingPopup.vue'
import PaymentPopup from '@/components/PaymentPopup.vue'
// Composables
import { useActivity, useIssues, useRewards, useRecords } from '@/composables'
@@ -164,6 +172,9 @@ const cabinetVisible = ref(false)
const showResultPopup = ref(false)
const drawResults = ref([])
const drawLoading = ref(false)
+const showDrawLoading = ref(false)
+const drawProgress = ref(0)
+const drawTotal = ref(1)
const isDevMode = ref(false)
const customDrawCount = ref(1)
@@ -353,6 +364,11 @@ async function onMachineDraw(count) {
})
})
+ // 支付成功后立即显示开奖加载弹窗
+ drawTotal.value = times
+ drawProgress.value = 0
+ showDrawLoading.value = true
+
// 轮询等待开奖完成
let resultRes = await getLotteryResult(orderNo)
let pollCount = 0
@@ -361,16 +377,22 @@ async function onMachineDraw(count) {
while (resultRes?.status === 'paid_waiting' &&
resultRes?.completed < resultRes?.count &&
pollCount < maxPolls) {
+ // 更新进度
+ drawProgress.value = resultRes?.completed || 0
await new Promise(r => setTimeout(r, resultRes?.nextPollMs || 2000))
resultRes = await getLotteryResult(orderNo)
pollCount++
}
+ // 隐藏加载弹窗
+ showDrawLoading.value = false
+
const items = mapResultsToFlipItems(resultRes, currentIssueRewards.value)
drawResults.value = items
showResultPopup.value = true
} catch (e) {
+ showDrawLoading.value = false
uni.showToast({ title: e.message || '操作失败', icon: 'none' })
} finally {
drawLoading.value = false
diff --git a/pages/cabinet/index.vue b/pages/cabinet/index.vue
index 7a408d7..ed54209 100644
--- a/pages/cabinet/index.vue
+++ b/pages/cabinet/index.vue
@@ -249,7 +249,7 @@ onShow(() => {
if (currentTab.value === 1) {
loadShipments(uid)
} else {
- loadAllInventory(uid)
+ loadInventory(uid) // 改为只加载第一页,后续由 onReachBottom 触发
}
})
@@ -265,6 +265,7 @@ onReachBottom(() => {
})
function switchTab(index) {
+ if (loading.value) return // 防止切换过快导致并发加载冲突
currentTab.value = index
// 切换时重新加载数据
page.value = 1
@@ -275,7 +276,7 @@ function switchTab(index) {
if (currentTab.value === 1) {
loadShipments(uid)
} else {
- loadAllInventory(uid)
+ loadInventory(uid) // 改为按需加载
}
}
@@ -498,6 +499,7 @@ async function loadInventory(uid) {
original_ids: [item.id], // 初始化 id 数组
name: (item.product_name || item.name || '').trim(),
image: imageUrl,
+ price: item.product_price ? item.product_price / 100 : null, // 直接使用后端返回的价格
count: 1,
selected: false,
selectedCount: 1,
@@ -594,33 +596,6 @@ async function loadInventory(uid) {
}
}
-async function loadAllInventory(uid) {
- try {
- while (hasMore.value) {
- await loadInventory(uid)
- }
- fetchProductPrices()
- } catch (e) {}
-}
-
-async function fetchProductPrices() {
- const currentList = currentTab.value === 1 ? shippedList : aggregatedList
- const list = currentList.value
- for (let i = 0; i < list.length; i++) {
- const item = list[i]
- if (item.id && !item.price) {
- try {
- const meta = await fetchProductMeta(item.id)
- if (meta) {
- if (!item.price && meta.price !== null) item.price = meta.price
- }
- } catch (e) {
- console.error('Fetch price failed for:', item.id, e)
- }
- }
- }
-}
-
function toggleSelect(item) {
uni.vibrateShort({ type: 'light' })
item.selected = !item.selected
diff --git a/pages/orders/detail.vue b/pages/orders/detail.vue
index 59ce509..6a242a5 100644
--- a/pages/orders/detail.vue
+++ b/pages/orders/detail.vue
@@ -54,7 +54,7 @@
已开启
- {{ order.reward_level }}赏
+ {{ getLevelLabel(order.reward_level) }}赏
@@ -234,6 +234,7 @@
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getOrderDetail, cancelOrder, createWechatOrder } from '../../api/appUser'
+import { levelToAlpha } from '@/utils/activity'
const orderId = ref('')
const order = ref(null)
@@ -433,6 +434,10 @@ function getSourceTypeText(type) {
return '其他'
}
+function getLevelLabel(level) {
+ return levelToAlpha(level)
+}
+
function showProofHelp() {
uni.showModal({
title: '抽奖凭证说明',
diff --git a/utils/activity.js b/utils/activity.js
index 1bf8862..0c6cff4 100644
--- a/utils/activity.js
+++ b/utils/activity.js
@@ -39,14 +39,32 @@ export function detectBoss(item) {
}
/**
- * 等级数字转字母 (1 -> A, 2 -> B, ...)
+ * 奖品等级映射 (与管理端保持一致)
+ */
+export const PRIZE_LEVEL_LABELS = {
+ 1: 'S',
+ 2: 'A',
+ 3: 'B',
+ 4: 'C',
+ 5: 'D',
+ 6: 'E',
+ 7: 'F',
+ 8: 'G',
+ 9: 'H',
+ 11: 'Last'
+}
+
+/**
+ * 等级数字转字母/标签
* @param {number|string} level - 等级
* @returns {string}
*/
export function levelToAlpha(level) {
if (level === 'BOSS') return 'BOSS'
const n = Number(level)
+ if (PRIZE_LEVEL_LABELS[n]) return PRIZE_LEVEL_LABELS[n]
if (isNaN(n) || n <= 0) return String(level || '赏')
+ // 兜底逻辑:如果超出定义的映射,使用 A, B, C...
return String.fromCharCode(64 + n)
}