You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
7.9 KiB
280 lines
7.9 KiB
<template> |
|
<div class="flex justify-between items-center h-[64px] px-5 bg-white"> |
|
<h1>金融产品设计及数字化营销沙盘系统</h1> |
|
<div class="inline-flex items-center"> |
|
<el-tooltip effect="light" |
|
content="退出实训" |
|
placement="bottom"> |
|
<img class="mr-3 cursor-pointer" |
|
src="@/assets/images/level/1.png" |
|
alt="" |
|
@click="logout" /> |
|
</el-tooltip> |
|
</div> |
|
</div> |
|
<div class="relative min-h-[calc(100vh-64px)] pt-5 pl-5 bg-[url('@/assets/images/level/4.png')] bg-[length:100%_100%] bg-no-repeat"> |
|
<div class="relative"> |
|
<div class="w-[354px] h-[68px] bg-[url('@/assets/images/level/5.png')] bg-[length:100%_100%] bg-no-repeat"></div> |
|
<div class="absolute top-5 left-40 flex items-center cursor-pointer" |
|
@click="getLevel(1)"> |
|
<img v-if="collected" |
|
src="@/assets/images/level/7.png" |
|
alt="" /> |
|
<img v-else |
|
src="@/assets/images/level/6.png" |
|
alt="" /> |
|
<span class="ml-2 text-sm text-[#999]">仅显示已收藏的项目</span> |
|
</div> |
|
</div> |
|
<div class="relative mt-5"> |
|
<div v-for="(item, i) in levels" |
|
:key="i" |
|
:class="['item', { active: curLevel === item.id }]" |
|
@click="selecLevel(item)"> |
|
<span class="num">LV.{{ i + 1 }}</span> |
|
<div class="texts"> |
|
<h6>第{{ numToChinese(item.name.split(' ')[0].replace('关卡', '')) }}关</h6> |
|
<p class="des mul-ellipsis2">{{ item.name.split(' ')[1] }}</p> |
|
<img v-if="item.collect" |
|
class="icon" |
|
src="@/assets/images/level/star2.png" |
|
alt="" |
|
@click.stop="collectItem(item)" /> |
|
<img v-else |
|
class="icon" |
|
src="@/assets/images/level/star1.png" |
|
alt="" |
|
@click.stop="collectItem(item)" /> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="arrow top-0 left-[50%] translate-x-[-50%] w-[64px] h-[64px] bg-[url('@/assets/images/level/arrow-up.png')]"></div> |
|
<div class="arrow right-0 top-[50%] translate-y-[-50%] w-[64px] h-[64px] bg-[url('@/assets/images/level/arrow-right.png')]"></div> |
|
<div class="arrow bottom-0 left-[50%] translate-x-[-50%] w-[64px] h-[64px] bg-[url('@/assets/images/level/arrow-down.png')]" |
|
@click="move"></div> |
|
<div class="arrow left-0 top-[50%] translate-y-[-50%] w-[64px] h-[64px] bg-[url('@/assets/images/level/arrow-left.png')]"></div> |
|
<div class="absolute bottom-2 right-1 w-[262px] h-[74px] bg-[url('@/assets/images/level/submit.png')] bg-[length:100%_100%] bg-no-repeat cursor-pointer hover:bg-[url('@/assets/images/level/submit-hover.png')]" |
|
@click="toRole"></div> |
|
</div> |
|
<Panel /> |
|
</template> |
|
|
|
<script setup lang="ts"> |
|
import { ref, onMounted } from 'vue'; |
|
import { checkPointList } from '@/api/judgment'; |
|
import { cancelCollection, collect } from '@/api/bank'; |
|
import Panel from '@/components/Panel/index.vue'; |
|
import { useRouter, useRoute } from 'vue-router'; |
|
import { ElMessage } from 'element-plus'; |
|
import { logout } from '@/store/useCurrentUser'; |
|
import { numToChinese } from '@/utils/common'; |
|
import Cookies from 'js-cookie'; |
|
|
|
const router = useRouter(); |
|
const route = useRoute(); |
|
const collected = ref<boolean>(false); |
|
const curLevel = ref<number | string>(''); |
|
const levels = ref<Record<string, any>[]>([]); |
|
const projectId = Cookies.get('sand-projectId') ?? route.query.projectId; |
|
// 关卡列表 |
|
const getLevel = async (only: any = '') => { |
|
if (only) collected.value = !collected.value; |
|
const { data } = await checkPointList(+projectId, collected.value ? 1 : ''); |
|
levels.value = data; |
|
}; |
|
// 点击关卡回调 |
|
const selecLevel = (item: Record<string, any>) => { |
|
curLevel.value = item.id; |
|
}; |
|
// 收藏 |
|
const collectItem = async (item: Record<string, any>) => { |
|
if (item.collect) { |
|
await cancelCollection(item.favoriteId); |
|
} else { |
|
await collect({ |
|
checkPointId: item.id, |
|
projectId, |
|
}); |
|
} |
|
getLevel(); |
|
}; |
|
// 确定 |
|
const toRole = () => { |
|
if (curLevel.value) { |
|
Cookies.set('sand-level', curLevel.value); |
|
router.push({ |
|
path: `/role`, |
|
query: { |
|
levelId: curLevel.value, |
|
}, |
|
}); |
|
} else { |
|
ElMessage.error('请选择关卡!'); |
|
} |
|
}; |
|
const move = () => { |
|
window.scrollTo(0, 100); |
|
}; |
|
onMounted(() => { |
|
getLevel(); |
|
}); |
|
</script> |
|
|
|
<style lang="scss" scoped> |
|
.item { |
|
--w: 330px; |
|
--line2: 160px; |
|
--line3: 360px; |
|
--line4: 520px; |
|
@apply absolute w-[218px] h-[120px] text-white bg-[url('@/assets/images/level/8.png')] bg-[length:100%_100%] bg-no-repeat cursor-pointer; |
|
&:before, |
|
&:after { |
|
content: ''; |
|
@apply absolute top-[86%] left-[100px] w-[90px] h-[70px] bg-[length:auto] bg-no-repeat; |
|
} |
|
.num { |
|
@apply absolute bottom-[37px] left-[12px] w-[60px] font-['DIN-BlackItalic'] text-center; |
|
text-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2); |
|
} |
|
.texts { |
|
@apply pl-[90px] pt-[10px] pr-[13px]; |
|
} |
|
h6 { |
|
@apply text-[#FFB627] text-lg font-['AlibabaPuHuiTi_2_105_Heavy'] rounded-[24px]; |
|
text-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2); |
|
background: linear-gradient(180deg, #fffcf0 0%, #ffc868 100%); |
|
-webkit-background-clip: text; |
|
-webkit-text-fill-color: transparent; |
|
} |
|
.des { |
|
@apply text-sm leading-[20px]; |
|
text-shadow: 0px 2px 4px rgba(0, 0, 0, 0.2); |
|
} |
|
.icon { |
|
@apply absolute top-[13px] right-[11px]; |
|
} |
|
&:hover { |
|
@apply opacity-80; |
|
} |
|
&.active { |
|
@apply bg-[url('@/assets/images/level/10.png')]; |
|
h6 { |
|
@apply bg-none; |
|
text-shadow: none; |
|
-webkit-text-fill-color: #fff; |
|
} |
|
} |
|
|
|
&:nth-child(2) { |
|
@apply top-[var(--line2)] left-[160px]; |
|
} |
|
&:nth-child(3) { |
|
@apply left-[var(--w)]; |
|
} |
|
&:nth-child(4) { |
|
@apply top-[var(--line2)] left-[510px]; |
|
} |
|
&:nth-child(5) { |
|
@apply left-[calc(var(--w)*2)]; |
|
} |
|
&:nth-child(6) { |
|
@apply top-[var(--line2)] left-[820px]; |
|
} |
|
&:nth-child(7) { |
|
@apply left-[calc(var(--w)*3)]; |
|
} |
|
&:nth-child(8) { |
|
@apply top-[var(--line2)] left-[1170px]; |
|
} |
|
&:nth-child(9) { |
|
@apply left-[calc(var(--w)*4)]; |
|
} |
|
&:nth-child(10) { |
|
@apply top-[var(--line2)] left-[1500px]; |
|
} |
|
&:nth-child(11) { |
|
@apply top-[var(--line3)] left-[1500px]; |
|
} |
|
&:nth-child(12) { |
|
@apply top-[var(--line4)] left-[calc(var(--w)*4)]; |
|
} |
|
&:nth-child(13) { |
|
@apply top-[var(--line3)] left-[1170px]; |
|
} |
|
&:nth-child(14) { |
|
@apply top-[var(--line4)] left-[calc(var(--w)*3)]; |
|
} |
|
&:nth-child(15) { |
|
@apply top-[var(--line3)] left-[820px]; |
|
} |
|
&:nth-child(16) { |
|
@apply top-[var(--line4)] left-[calc(var(--w)*2)]; |
|
} |
|
&:nth-child(17) { |
|
@apply top-[var(--line3)] left-[510px]; |
|
} |
|
&:nth-child(18) { |
|
@apply top-[var(--line4)] left-[var(--w)]; |
|
} |
|
&:nth-child(19) { |
|
@apply top-[var(--line3)] left-[160px]; |
|
} |
|
&:nth-child(20) { |
|
@apply top-[var(--line4)]; |
|
} |
|
|
|
&:nth-child(odd) { |
|
&:before { |
|
@apply left-[40px] bg-[url('@/assets/images/level/line2.png')]; |
|
transform: rotateX(180deg); |
|
} |
|
&:after { |
|
@apply bg-[url('@/assets/images/level/line2.png')]; |
|
} |
|
} |
|
&:first-child { |
|
z-index: 1; |
|
&:before { |
|
display: none; |
|
} |
|
&:after { |
|
@apply bg-[url('@/assets/images/level/line2.png')]; |
|
} |
|
} |
|
&:nth-child(10) { |
|
&:before { |
|
display: none; |
|
} |
|
&:after { |
|
@apply left-[108px] h-[98px] bg-[url('@/assets/images/level/line3.png')]; |
|
} |
|
} |
|
&:nth-child(11) { |
|
&:before { |
|
@apply left-[40px] bg-[url('@/assets/images/level/line2.png')]; |
|
transform: rotateX(180deg); |
|
} |
|
&:after { |
|
display: none; |
|
} |
|
} |
|
} |
|
.arrow { |
|
@apply absolute bg-[length:100%_100%] bg-no-repeat animate-bounce cursor-pointer; |
|
} |
|
|
|
@keyframes bounce { |
|
0%, |
|
100% { |
|
// transform: translateY(-250%); |
|
margin-top: -10px; |
|
animation-timing-function: cubic-bezier(0.8, 0, 1, 1); |
|
} |
|
50% { |
|
// transform: translateY(0); |
|
margin-top: 0; |
|
animation-timing-function: cubic-bezier(0, 0, 0.2, 1); |
|
} |
|
} |
|
</style>
|
|
|