341 lines
8.3 KiB
Vue
341 lines
8.3 KiB
Vue
<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>
|