From 75638f895b4b5b757cb6bf49049d8ab87eb2db35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=96=B9=E6=88=90?= Date: Sat, 27 Dec 2025 21:21:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=BC=80=E5=A5=96?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E5=BC=B9=E7=AA=97=E7=BB=84=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E7=BB=9F=E4=B8=80=E6=B4=BB=E5=8A=A8=E7=AD=89=E7=BA=A7=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E9=80=BB=E8=BE=91=EF=BC=8C=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9F=9C=E5=AD=90=E5=BA=93=E5=AD=98=E5=8A=A0=E8=BD=BD=E6=80=A7?= =?UTF-8?q?=E8=83=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/activity/DrawLoadingPopup.vue | 319 +++++++++++++++++++++++ composables/useRecords.js | 6 +- pages/activity/duiduipeng/index.vue | 8 +- pages/activity/wuxianshang/index.vue | 22 ++ pages/cabinet/index.vue | 33 +-- pages/orders/detail.vue | 7 +- utils/activity.js | 20 +- 7 files changed, 374 insertions(+), 41 deletions(-) create mode 100644 components/activity/DrawLoadingPopup.vue 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 @@ + + + + + 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) }