ai_images/portal-ui/src/views/Recharge.vue

372 lines
6.7 KiB
Vue

<template>
<div :class="prefixCls">
<div :class="`${prefixCls}-left`">
<a-menu
:mode="mode"
v-if="dataList?.length"
theme="dark"
:selected-keys="selectedKeys"
:collapsed="collapsed"
:default-open-keys="defaultOpenedKeys"
@menu-item-click="menuItemClick"
@sub-menu-click="subMenuClick">
<template v-for="item in dataList">
<template v-if="item.children && item.children.length > 0">
<a-sub-menu
:key="item.id"
:title="item.title">
<template #icon>
<mf-icon
v-if="item.icon"
:value="item.icon" />
</template>
<a-menu-item
v-for="child in item.children"
:key="child.key">
{{ child.title }}
</a-menu-item>
</a-sub-menu>
</template>
<template v-else>
<a-menu-item :key="item.id">
<template #icon>
<mf-icon
v-if="item.icon"
:value="item.icon" />
</template>
<div class="menu-item">
{{ item.title }}
</div>
</a-menu-item>
</template>
</template>
</a-menu>
</div>
<div :class="`${prefixCls}-right`">
<div :class="`${prefixCls}-right-banner`">
<a-carousel>
<a-carousel-item
v-for="item in images"
@click="jumpUrl(item)">
<a-image
:src="item.imageUrl"
:preview="false"
fit="cover"
width="100%"
height="100%" />
</a-carousel-item>
</a-carousel>
</div>
<div :class="`${prefixCls}-right-content`">
<mf-recharge-pc
:recharge-id="selectedKeys[0]"
:apiUrl="apiUrl" />
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, inject, onMounted, watch } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
const router = useRouter()
const prefixCls = 'recharge'
const $datas = inject('$datas')
const $axios = inject('$axios')
const $base = inject('$base')
const $message = inject('$message')
const defaultOpenedKeys = ref(['1'])
const selectedKeys = ref([])
const collapsed = ref(false)
const dataList = ref([])
const giftList = ref([])
const store = useStore()
const rechargeLoading = ref(false)
const images = ref([])
const rechargeVisible = ref(false)
const apiUrl = ref('')
const rechargeUrl = ref('')
const mode = $base.isMobile() ? 'horizontal' : 'vertical'
onMounted(() => {
getBanner()
getData()
})
watch(
() => store.getters.lang,
() => {
getData()
}
)
const getData = () => {
$axios({
url: 'api/gift/getGiftList',
method: 'GET'
}).then((res) => {
dataList.value = res.data
?.filter((d) => d.payType)
.map((item) => {
return {
...item,
title: item.payType
}
})
let rechargeId = dataList.value[0].id
selectedKeys.value = [rechargeId]
apiUrl.value = dataList.value[0].apiUrl
getGiftInfo(rechargeId)
})
}
const getGiftInfo = (rechargeId) => {
$axios({
url: 'api/gift/getGiftInfo',
method: 'GET',
data: {
rechargeId
}
}).then((res) => {
giftList.value = res.data
})
}
const menuItemClick = (key) => {
selectedKeys.value = [key]
let item = dataList.value.find((d) => d.id == key)
apiUrl.value = item?.apiUrl
}
const subMenuClick = (key, _openKeys) => {}
const jumpUrl = (item) => {
if (item.type == 0) {
router.push(item.jumpUrl)
} else if (item.type == 1) {
window.open(item.jumpUrl)
}
}
const getBanner = () => {
$axios({
url: 'api/banner/getBannerList',
method: 'GET',
data: {
position: 1
}
}).then((res) => {
images.value = res.rows
})
}
const showRecharge = () => {
rechargeVisible.value = true
}
</script>
<style lang="less" scoped>
.recharge {
display: flex;
height: 100%;
&-left {
height: 100%;
width: clamp(160px, 12vw, 200px);
overflow-y: auto;
flex-shrink: 0;
.arco-menu-dark {
background-color: transparent;
.arco-menu-item {
margin-bottom: 12px;
background-color: transparent;
&:hover,
&.arco-menu-selected {
background-color: rgb(var(--primary-6));
border-radius: 10px;
}
}
}
}
&-right {
flex-grow: 1;
padding: 0 clamp(12px, 4vw, 60px) clamp(20px, 4vw, 60px) clamp(12px, 2vw, 20px);
overflow-y: auto;
min-width: 0; // 防止 flex 子元素溢出
&-banner {
width: 100%;
aspect-ratio: 6 / 1;
margin-bottom: clamp(20px, 3vw, 40px);
border-radius: 10px;
overflow: hidden;
cursor: pointer;
:deep(.arco-carousel) {
width: 100%;
height: 100%;
&-arrow {
> div {
width: 36px;
height: 36px;
background-color: rgba(0, 0, 0, 0.3);
.arco-icon {
width: 20px;
height: 20px;
}
}
}
}
}
&-qrcode {
width: 300px;
height: 300px;
background: #1a1b20;
border-radius: 10px;
padding: 10px;
.arco-image {
border-radius: 5px;
}
}
&-wallet {
font-size: 14px;
color: #ffffff;
line-height: 24px;
margin-top: 30px;
}
&-recharge {
margin-top: 20px;
width: 120px;
border-radius: 10px;
}
&-content {
position: relative;
background-size: cover;
background-position: center;
border-radius: 10px;
&-wrapper {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
backdrop-filter: blur(12px);
background: linear-gradient(
90deg,
rgba(39, 20, 51, 0.5) 0%,
rgba(230, 33, 122, 0.5) 49%,
rgba(39, 20, 51, 0.5) 100%
);
}
}
&-tips {
margin-bottom: 40px;
p {
font-size: 14px;
color: #ffffff;
line-height: 24px;
margin-bottom: 4px;
}
}
}
&-content {
color: #fff;
padding: 0 40px;
background-color: #000;
* {
color: #999999 !important;
background-color: transparent !important;
}
}
}
// 平板和中等屏幕 (768px - 1024px)
@media (min-width: 768px) and (max-width: 1024px) {
.recharge {
&-left {
width: clamp(140px, 15vw, 180px);
}
&-right {
padding: 0 clamp(16px, 3vw, 40px) clamp(20px, 3vw, 40px) clamp(12px, 2vw, 20px);
}
}
}
// 移动端 (≤576px)
@media (max-width: 576px) {
.recharge {
flex-direction: column;
&-left {
width: 100%;
height: auto;
margin-bottom: 0px;
:deep(.arco-menu-dark) {
background-color: transparent;
.arco-menu-inner {
padding: 0;
}
.arco-menu-item {
width: 150px;
height: 40px;
text-align: center;
line-height: 40px;
.arco-menu-icon {
display: none;
}
}
.arco-menu-selected-label {
display: none;
}
}
}
&-right {
padding: 12px;
:deep(.arco-carousel) {
height: 160px;
.arco-image {
height: 100%;
img {
height: 100%;
}
}
}
&-banner {
height: 160px;
margin-bottom: 20px;
}
}
}
}
</style>