feat: 新增开奖加载弹窗组件,统一活动等级显示逻辑,并优化柜子库存加载性能。
This commit is contained in:
parent
e19ec06d74
commit
75638f895b
319
components/activity/DrawLoadingPopup.vue
Normal file
319
components/activity/DrawLoadingPopup.vue
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="visible" class="draw-loading-overlay" @touchmove.stop.prevent>
|
||||||
|
<!-- 背景渐变 -->
|
||||||
|
<view class="bg-gradient"></view>
|
||||||
|
|
||||||
|
<!-- 光圈效果 -->
|
||||||
|
<view class="light-ring"></view>
|
||||||
|
<view class="light-ring ring-2"></view>
|
||||||
|
|
||||||
|
<!-- 主内容 -->
|
||||||
|
<view class="loading-content">
|
||||||
|
<!-- 3D礼盒动画 -->
|
||||||
|
<view class="gift-container">
|
||||||
|
<view class="gift-box">
|
||||||
|
<view class="gift-lid">
|
||||||
|
<view class="lid-top"></view>
|
||||||
|
<view class="lid-ribbon"></view>
|
||||||
|
</view>
|
||||||
|
<view class="gift-body">
|
||||||
|
<view class="body-ribbon"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 闪光粒子 -->
|
||||||
|
<view class="sparkle sparkle-1">✨</view>
|
||||||
|
<view class="sparkle sparkle-2">⭐</view>
|
||||||
|
<view class="sparkle sparkle-3">✨</view>
|
||||||
|
<view class="sparkle sparkle-4">💫</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 文字区域 -->
|
||||||
|
<view class="text-area">
|
||||||
|
<text class="loading-title">{{ title }}</text>
|
||||||
|
<view class="loading-dots">
|
||||||
|
<view class="dot"></view>
|
||||||
|
<view class="dot"></view>
|
||||||
|
<view class="dot"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 进度条(当有多次抽奖时显示) -->
|
||||||
|
<view v-if="total > 1" class="progress-area">
|
||||||
|
<view class="progress-bar">
|
||||||
|
<view class="progress-fill" :style="{ width: progressPercent + '%' }"></view>
|
||||||
|
</view>
|
||||||
|
<text class="progress-text">{{ progress }} / {{ total }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示文字 -->
|
||||||
|
<text class="tip-text">请稍候,好运即将到来...</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
visible: { type: Boolean, default: false },
|
||||||
|
title: { type: String, default: '正在开奖中' },
|
||||||
|
progress: { type: Number, default: 0 },
|
||||||
|
total: { type: Number, default: 1 }
|
||||||
|
})
|
||||||
|
|
||||||
|
const progressPercent = computed(() => {
|
||||||
|
if (props.total <= 0) return 0
|
||||||
|
return Math.min(100, Math.round((props.progress / props.total) * 100))
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.draw-loading-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0; left: 0; right: 0; bottom: 0;
|
||||||
|
z-index: 2000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
animation: fadeIn 0.3s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 背景 */
|
||||||
|
.bg-gradient {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: radial-gradient(ellipse at center,
|
||||||
|
rgba(255, 140, 0, 0.15) 0%,
|
||||||
|
rgba(30, 20, 50, 0.98) 50%,
|
||||||
|
rgba(10, 5, 20, 0.99) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 光圈 */
|
||||||
|
.light-ring {
|
||||||
|
position: absolute;
|
||||||
|
width: 500rpx; height: 500rpx;
|
||||||
|
border: 4rpx solid rgba(255, 200, 100, 0.3);
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: ringExpand 2s ease-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ring-2 {
|
||||||
|
animation-delay: 1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes ringExpand {
|
||||||
|
0% {
|
||||||
|
transform: scale(0.5);
|
||||||
|
opacity: 0.8;
|
||||||
|
border-width: 8rpx;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(2);
|
||||||
|
opacity: 0;
|
||||||
|
border-width: 2rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 主内容 */
|
||||||
|
.loading-content {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10;
|
||||||
|
animation: contentPop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes contentPop {
|
||||||
|
from { opacity: 0; transform: scale(0.8); }
|
||||||
|
to { opacity: 1; transform: scale(1); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 礼盒容器 */
|
||||||
|
.gift-container {
|
||||||
|
position: relative;
|
||||||
|
width: 240rpx;
|
||||||
|
height: 240rpx;
|
||||||
|
margin-bottom: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 礼盒动画 */
|
||||||
|
.gift-box {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%; top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
animation: boxBounce 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes boxBounce {
|
||||||
|
0%, 100% { transform: translate(-50%, -50%); }
|
||||||
|
50% { transform: translate(-50%, -60%); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-lid {
|
||||||
|
position: relative;
|
||||||
|
animation: lidShake 1.5s ease-in-out infinite;
|
||||||
|
transform-origin: center bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes lidShake {
|
||||||
|
0%, 100% { transform: rotate(0deg) translateY(0); }
|
||||||
|
25% { transform: rotate(-5deg) translateY(-10rpx); }
|
||||||
|
75% { transform: rotate(5deg) translateY(-10rpx); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.lid-top {
|
||||||
|
width: 140rpx; height: 30rpx;
|
||||||
|
background: linear-gradient(135deg, #FF6B35, #FF8C00);
|
||||||
|
border-radius: 8rpx 8rpx 0 0;
|
||||||
|
box-shadow: 0 -4rpx 16rpx rgba(255, 107, 53, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.lid-ribbon {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%; top: -20rpx;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 40rpx; height: 50rpx;
|
||||||
|
background: linear-gradient(135deg, #FFD700, #FFA500);
|
||||||
|
border-radius: 8rpx;
|
||||||
|
|
||||||
|
&::before, &::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 36rpx;
|
||||||
|
width: 30rpx; height: 30rpx;
|
||||||
|
background: linear-gradient(135deg, #FFD700, #FFA500);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
&::before { left: -20rpx; }
|
||||||
|
&::after { right: -20rpx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.gift-body {
|
||||||
|
width: 120rpx; height: 100rpx;
|
||||||
|
background: linear-gradient(135deg, #FF8C00, #FF6B35);
|
||||||
|
border-radius: 0 0 12rpx 12rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: -2rpx;
|
||||||
|
box-shadow:
|
||||||
|
0 12rpx 32rpx rgba(255, 107, 53, 0.4),
|
||||||
|
inset 0 -10rpx 20rpx rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.body-ribbon {
|
||||||
|
width: 30rpx; height: 100%;
|
||||||
|
background: linear-gradient(180deg, #FFD700, #FFA500);
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 闪光粒子 */
|
||||||
|
.sparkle {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 32rpx;
|
||||||
|
animation: sparkleFloat 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sparkle-1 { top: 10rpx; left: 20rpx; animation-delay: 0s; }
|
||||||
|
.sparkle-2 { top: 30rpx; right: 20rpx; animation-delay: 0.5s; }
|
||||||
|
.sparkle-3 { bottom: 40rpx; left: 0; animation-delay: 1s; }
|
||||||
|
.sparkle-4 { bottom: 20rpx; right: 10rpx; animation-delay: 1.5s; }
|
||||||
|
|
||||||
|
@keyframes sparkleFloat {
|
||||||
|
0%, 100% {
|
||||||
|
opacity: 0.4;
|
||||||
|
transform: translateY(0) scale(0.8);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(-20rpx) scale(1.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 文字区域 */
|
||||||
|
.text-area {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-title {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #FFF;
|
||||||
|
text-shadow: 0 0 30rpx rgba(255, 180, 100, 0.8);
|
||||||
|
letter-spacing: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-dots {
|
||||||
|
display: flex;
|
||||||
|
gap: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
width: 12rpx; height: 12rpx;
|
||||||
|
background: #FFD700;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: dotBounce 1.4s ease-in-out infinite;
|
||||||
|
|
||||||
|
&:nth-child(1) { animation-delay: 0s; }
|
||||||
|
&:nth-child(2) { animation-delay: 0.2s; }
|
||||||
|
&:nth-child(3) { animation-delay: 0.4s; }
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dotBounce {
|
||||||
|
0%, 80%, 100% {
|
||||||
|
transform: scale(0.6);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
40% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 进度条 */
|
||||||
|
.progress-area {
|
||||||
|
width: 400rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
height: 16rpx;
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
border-radius: 8rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: inset 0 2rpx 4rpx rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-fill {
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, #FFD700, #FF8C00, #FF6B35);
|
||||||
|
border-radius: 8rpx;
|
||||||
|
transition: width 0.3s ease-out;
|
||||||
|
box-shadow: 0 0 16rpx rgba(255, 200, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-text {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
margin-top: 12rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示文字 */
|
||||||
|
.tip-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.6);
|
||||||
|
letter-spacing: 2rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { getIssueDrawLogs } from '@/api/appUser'
|
import { getIssueDrawLogs } from '@/api/appUser'
|
||||||
|
import { levelToAlpha } from '@/utils/activity'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 购买记录管理
|
* 购买记录管理
|
||||||
@ -55,9 +56,8 @@ export function useRecords() {
|
|||||||
|
|
||||||
function getLevelName(level) {
|
function getLevelName(level) {
|
||||||
if (!level) return ''
|
if (!level) return ''
|
||||||
// 尝试映射 1->A, 2->B ...
|
const alpha = levelToAlpha(level)
|
||||||
const map = { 1: 'A', 2: 'B', 3: 'C', 4: 'D', 5: 'E', 6: 'F', 7: 'G', 8: 'H', 9: 'I', 10: 'J' }
|
return alpha + '赏'
|
||||||
return map[level] || (level + '赏')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearRecords() {
|
function clearRecords() {
|
||||||
|
|||||||
@ -187,6 +187,7 @@ import RecordsList from '@/components/activity/RecordsList.vue'
|
|||||||
import RulesPopup from '@/components/activity/RulesPopup.vue'
|
import RulesPopup from '@/components/activity/RulesPopup.vue'
|
||||||
import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
|
import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
|
||||||
import { getActivityDetail, getActivityIssues, getActivityIssueRewards, getUserCoupons, getItemCards, createWechatOrder, getMatchingCardTypes, createMatchingPreorder, checkMatchingGame, getIssueDrawLogs, getMatchingGameCards } from '../../../api/appUser'
|
import { getActivityDetail, getActivityIssues, getActivityIssueRewards, getUserCoupons, getItemCards, createWechatOrder, getMatchingCardTypes, createMatchingPreorder, checkMatchingGame, getIssueDrawLogs, getMatchingGameCards } from '../../../api/appUser'
|
||||||
|
import { levelToAlpha } from '@/utils/activity'
|
||||||
|
|
||||||
const detail = ref({})
|
const detail = ref({})
|
||||||
const statusText = ref('')
|
const statusText = ref('')
|
||||||
@ -634,13 +635,6 @@ function formatPercent(v) {
|
|||||||
return `${n}%`
|
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() {
|
function openRewardsPopup() {
|
||||||
rewardsVisible.value = true
|
rewardsVisible.value = true
|
||||||
|
|||||||
@ -103,6 +103,13 @@
|
|||||||
v-model:visible="cabinetVisible"
|
v-model:visible="cabinetVisible"
|
||||||
:activity-id="activityId"
|
:activity-id="activityId"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 开奖加载弹窗 -->
|
||||||
|
<DrawLoadingPopup
|
||||||
|
:visible="showDrawLoading"
|
||||||
|
:progress="drawProgress"
|
||||||
|
:total="drawTotal"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</ActivityPageLayout>
|
</ActivityPageLayout>
|
||||||
</template>
|
</template>
|
||||||
@ -120,6 +127,7 @@ import RecordsList from '@/components/activity/RecordsList.vue'
|
|||||||
import RulesPopup from '@/components/activity/RulesPopup.vue'
|
import RulesPopup from '@/components/activity/RulesPopup.vue'
|
||||||
import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
|
import CabinetPreviewPopup from '@/components/activity/CabinetPreviewPopup.vue'
|
||||||
import LotteryResultPopup from '@/components/activity/LotteryResultPopup.vue'
|
import LotteryResultPopup from '@/components/activity/LotteryResultPopup.vue'
|
||||||
|
import DrawLoadingPopup from '@/components/activity/DrawLoadingPopup.vue'
|
||||||
import PaymentPopup from '@/components/PaymentPopup.vue'
|
import PaymentPopup from '@/components/PaymentPopup.vue'
|
||||||
// Composables
|
// Composables
|
||||||
import { useActivity, useIssues, useRewards, useRecords } from '@/composables'
|
import { useActivity, useIssues, useRewards, useRecords } from '@/composables'
|
||||||
@ -164,6 +172,9 @@ const cabinetVisible = ref(false)
|
|||||||
const showResultPopup = ref(false)
|
const showResultPopup = ref(false)
|
||||||
const drawResults = ref([])
|
const drawResults = ref([])
|
||||||
const drawLoading = ref(false)
|
const drawLoading = ref(false)
|
||||||
|
const showDrawLoading = ref(false)
|
||||||
|
const drawProgress = ref(0)
|
||||||
|
const drawTotal = ref(1)
|
||||||
|
|
||||||
const isDevMode = ref(false)
|
const isDevMode = ref(false)
|
||||||
const customDrawCount = ref(1)
|
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 resultRes = await getLotteryResult(orderNo)
|
||||||
let pollCount = 0
|
let pollCount = 0
|
||||||
@ -361,16 +377,22 @@ async function onMachineDraw(count) {
|
|||||||
while (resultRes?.status === 'paid_waiting' &&
|
while (resultRes?.status === 'paid_waiting' &&
|
||||||
resultRes?.completed < resultRes?.count &&
|
resultRes?.completed < resultRes?.count &&
|
||||||
pollCount < maxPolls) {
|
pollCount < maxPolls) {
|
||||||
|
// 更新进度
|
||||||
|
drawProgress.value = resultRes?.completed || 0
|
||||||
await new Promise(r => setTimeout(r, resultRes?.nextPollMs || 2000))
|
await new Promise(r => setTimeout(r, resultRes?.nextPollMs || 2000))
|
||||||
resultRes = await getLotteryResult(orderNo)
|
resultRes = await getLotteryResult(orderNo)
|
||||||
pollCount++
|
pollCount++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 隐藏加载弹窗
|
||||||
|
showDrawLoading.value = false
|
||||||
|
|
||||||
const items = mapResultsToFlipItems(resultRes, currentIssueRewards.value)
|
const items = mapResultsToFlipItems(resultRes, currentIssueRewards.value)
|
||||||
|
|
||||||
drawResults.value = items
|
drawResults.value = items
|
||||||
showResultPopup.value = true
|
showResultPopup.value = true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
showDrawLoading.value = false
|
||||||
uni.showToast({ title: e.message || '操作失败', icon: 'none' })
|
uni.showToast({ title: e.message || '操作失败', icon: 'none' })
|
||||||
} finally {
|
} finally {
|
||||||
drawLoading.value = false
|
drawLoading.value = false
|
||||||
|
|||||||
@ -249,7 +249,7 @@ onShow(() => {
|
|||||||
if (currentTab.value === 1) {
|
if (currentTab.value === 1) {
|
||||||
loadShipments(uid)
|
loadShipments(uid)
|
||||||
} else {
|
} else {
|
||||||
loadAllInventory(uid)
|
loadInventory(uid) // 改为只加载第一页,后续由 onReachBottom 触发
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -265,6 +265,7 @@ onReachBottom(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function switchTab(index) {
|
function switchTab(index) {
|
||||||
|
if (loading.value) return // 防止切换过快导致并发加载冲突
|
||||||
currentTab.value = index
|
currentTab.value = index
|
||||||
// 切换时重新加载数据
|
// 切换时重新加载数据
|
||||||
page.value = 1
|
page.value = 1
|
||||||
@ -275,7 +276,7 @@ function switchTab(index) {
|
|||||||
if (currentTab.value === 1) {
|
if (currentTab.value === 1) {
|
||||||
loadShipments(uid)
|
loadShipments(uid)
|
||||||
} else {
|
} else {
|
||||||
loadAllInventory(uid)
|
loadInventory(uid) // 改为按需加载
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +499,7 @@ async function loadInventory(uid) {
|
|||||||
original_ids: [item.id], // 初始化 id 数组
|
original_ids: [item.id], // 初始化 id 数组
|
||||||
name: (item.product_name || item.name || '').trim(),
|
name: (item.product_name || item.name || '').trim(),
|
||||||
image: imageUrl,
|
image: imageUrl,
|
||||||
|
price: item.product_price ? item.product_price / 100 : null, // 直接使用后端返回的价格
|
||||||
count: 1,
|
count: 1,
|
||||||
selected: false,
|
selected: false,
|
||||||
selectedCount: 1,
|
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) {
|
function toggleSelect(item) {
|
||||||
uni.vibrateShort({ type: 'light' })
|
uni.vibrateShort({ type: 'light' })
|
||||||
item.selected = !item.selected
|
item.selected = !item.selected
|
||||||
|
|||||||
@ -54,7 +54,7 @@
|
|||||||
<text class="tag-text">已开启</text>
|
<text class="tag-text">已开启</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="level-tag" v-if="order.reward_level">
|
<view class="level-tag" v-if="order.reward_level">
|
||||||
<text class="tag-text">{{ order.reward_level }}赏</text>
|
<text class="tag-text">{{ getLevelLabel(order.reward_level) }}赏</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -234,6 +234,7 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { getOrderDetail, cancelOrder, createWechatOrder } from '../../api/appUser'
|
import { getOrderDetail, cancelOrder, createWechatOrder } from '../../api/appUser'
|
||||||
|
import { levelToAlpha } from '@/utils/activity'
|
||||||
|
|
||||||
const orderId = ref('')
|
const orderId = ref('')
|
||||||
const order = ref(null)
|
const order = ref(null)
|
||||||
@ -433,6 +434,10 @@ function getSourceTypeText(type) {
|
|||||||
return '其他'
|
return '其他'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getLevelLabel(level) {
|
||||||
|
return levelToAlpha(level)
|
||||||
|
}
|
||||||
|
|
||||||
function showProofHelp() {
|
function showProofHelp() {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '抽奖凭证说明',
|
title: '抽奖凭证说明',
|
||||||
|
|||||||
@ -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 - 等级
|
* @param {number|string} level - 等级
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
export function levelToAlpha(level) {
|
export function levelToAlpha(level) {
|
||||||
if (level === 'BOSS') return 'BOSS'
|
if (level === 'BOSS') return 'BOSS'
|
||||||
const n = Number(level)
|
const n = Number(level)
|
||||||
|
if (PRIZE_LEVEL_LABELS[n]) return PRIZE_LEVEL_LABELS[n]
|
||||||
if (isNaN(n) || n <= 0) return String(level || '赏')
|
if (isNaN(n) || n <= 0) return String(level || '赏')
|
||||||
|
// 兜底逻辑:如果超出定义的映射,使用 A, B, C...
|
||||||
return String.fromCharCode(64 + n)
|
return String.fromCharCode(64 + n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user