aslan-h5/src/views/ItemDistribution.vue

341 lines
8.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="fullPage">
<div class="bg">
<MobileHeader title="Item Distribution" />
<!-- 标签 -->
<div
style="
display: flex;
justify-content: space-around;
border-bottom: 1px solid #cccccc;
background-color: transparent;
position: relative;
"
>
<div
v-for="(item, index) in tabList"
:key="index"
style="font-size: 18px; padding: 10px 0; flex: 1; text-align: center"
class="tab-item"
:class="activeIndex == index ? 'tabName-active' : 'tabName'"
ref="tabItems"
@click="setActiveTab(index)"
>
{{ item.name }}
</div>
<!-- 下划线元素 -->
<div
style="width: 15px; height: 3px; background-color: #bb92ff"
:style="underlineStyle"
></div>
</div>
<!-- 商品列表 -->
<div
style="
width: 100%;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
padding: 15px;
"
>
<div v-for="(product, index) in productList" :key="index" @click="showSendDialog(product)">
<div
style="
background-color: white;
border-radius: 10px;
box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.2);
display: flex;
flex-direction: column;
align-items: center;
"
>
<img :src="product.cover" alt="虚拟商品" style="width: 60%; margin: 10px 0" />
<button
style="
background-color: #bb92ff;
color: white;
margin-bottom: 10px;
border: 0;
border-radius: 20px;
padding: 5px 10px;
"
>
Send
</button>
</div>
</div>
</div>
<!-- 弹窗 -->
<!-- 遮罩层 -->
<maskLayer :maskLayerShow="dialogshow" @click="closedPopup">
<div
style="
padding: 20px;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
border-radius: 20px;
margin: 20% 5%;
"
@click.stop
>
<img :src="selectedGoods.cover" alt="" style="width: 60%; margin: 5px 0" />
<div style="font-weight: 600; font-size: 16px; margin: 10px 0">
<span style="color: #00000080; margin-right: 10px">Validity:</span>
<span style="font-weight: 700; color: #000">{{ validityPeriod }}day</span>
</div>
<div>
<input
type="text"
placeholder="Enter user ID"
style="
height: 36px;
width: 171px;
border-radius: 8px;
border: 0;
background-color: #f1f1f1b2;
padding: 8px;
margin-right: 4px;
font-size: 14px;
font-weight: 590;
"
v-model="targetUserId"
/>
<button
style="
height: 36px;
width: 72px;
border-radius: 8px;
border: 0;
padding: 8px;
color: white;
font-size: 14px;
font-weight: 590;
"
:style="{ backgroundColor: confirmClick ? '#bb92ff' : '#00000080' }"
@click="sendGoods"
>
Confirm
</button>
</div>
</div>
</maskLayer>
</div>
</div>
</template>
<script setup>
import MobileHeader from '../components/MobileHeader.vue'
import maskLayer from '../components/MaskLayer.vue'
import { onMounted, ref, computed } from 'vue'
import { getAdminCenterList, giveProps, hasSendGiftsPermission } from '@/api/itemDistribution'
import { searchUser } from '@/api/userInfo'
import { showError, showWarning, showInfo, showSuccess } from '@/utils/toast.js'
const tabList = ref([
{
id: 1,
name: 'Frames',
},
{
id: 2,
name: 'Vehicles',
},
// {
// id: 3,
// name: 'Chat Box',
// },
// {
// id: 4,
// name: 'Theme',
// },
])
const activeIndex = ref(0)
const currentTab = ref('Frames') //选中名字
const tabItems = ref([]) // 存储标签DOM引用
const confirmClick = ref(true)
// 选择标签
const setActiveTab = (index) => {
if (activeIndex.value != index) {
console.log('切换标签')
productList.value = [] //置空商品列表
activeIndex.value = index
currentTab.value = tabList.value[index].name
loadProps()
}
}
// 计算下划线样式
const underlineStyle = computed(() => {
console.log('计算属性')
if (tabItems.value.length === 0) return {} //没有这个元素
const activeTab = tabItems.value[activeIndex.value]
console.log('选中元素的左边距', activeTab.offsetLeft)
return {
position: 'absolute',
left: `${activeTab.offsetLeft + activeTab.offsetWidth / 2 - 15 / 2}px`,
bottom: '0',
transition: 'left 0.3s ease', // 平滑过渡
}
})
const targetUserId = ref('')
// 检查是否有赠送某个栏目商品的资格
const getHasSendVIPPermission = async (propsType) => {
const response = await hasSendGiftsPermission(propsType)
console.log('response:', response)
return response.body
}
const sendGoods = async () => {
if (confirmClick.value) {
confirmClick.value = false
console.log('赠送用户id', targetUserId.value)
console.log('赠送商品:', selectedGoods.value)
try {
const targetUserInfo = await searchUser(targetUserId.value)
console.log('targetUserInfo:', targetUserInfo)
if (targetUserInfo.status && targetUserInfo.body) {
const data = {
propsId: selectedGoods.value.id,
acceptUserId: targetUserInfo.body.id,
}
const res = await giveProps(data)
if (res.errorCode == 0 && res.status) {
closedPopup()
showSuccess('Gift delivery successful')
} else {
confirmClick.value = true
}
} else {
confirmClick.value = true
}
} catch (error) {
console.log('error:', error)
// 信息提示id有误
showWarning(error.response.errorMsg)
confirmClick.value = true
throw error
}
}
}
// 选中的标签
const getPropsType = () => {
const typeMap = {
Frames: 'AVATAR_FRAME',
Vehicles: 'RIDE',
'Chat Box': 'CHAT_BUBBLE',
Theme: 'THEME',
VIP: 'NOBLE_VIP',
}
return typeMap[currentTab.value]
}
// 获取商品列表
const loadProps = async () => {
try {
const params = {
propsType: getPropsType(),
currencyType: 'GOLD',
}
const response = await getAdminCenterList(params)
console.log('response:', response)
productList.value = response.body
} catch (error) {
throw error
}
}
// 虚拟商品数据
const productList = ref([])
// 选中商品
const selectedGoods = ref({})
const validityPeriod = computed(() => {
return currentTab.value == 'VIP' ? '3' : '7'
})
// 获取本地图片
const getImageUrl = (imgUrl) => {
return new URL(imgUrl, import.meta.url).href
}
const dialogshow = ref(false)
// 展示弹窗
const showSendDialog = (product) => {
console.log('product:', product)
selectedGoods.value = product
dialogshow.value = true
}
// 关闭弹窗
const closedPopup = () => {
confirmClick.value = true
selectedGoods.value = {}
targetUserId.value = ''
dialogshow.value = false
}
onMounted(() => {
console.log('onMounted')
// 检查是否有赠送VIP的资格
if (getHasSendVIPPermission('NOBLE_VIP')) {
tabList.value.push({
id: 3,
name: 'VIP',
})
}
if (tabItems.value.length > 0) {
underlineStyle.value // 触发计算属性更新
}
loadProps()
})
</script>
<style scoped>
* {
color: black;
font-family: 'SF Pro';
}
.fullPage {
background-color: #ffffff;
min-height: 100vh;
position: relative;
}
.bg {
width: 100vw;
min-height: 100vh;
background-image: url(../assets/images/secondBg.png);
background-size: 100% auto;
background-repeat: no-repeat;
}
.tabName {
color: #00000066;
}
.tabName-active {
color: black;
font-weight: 500;
}
</style>