11 changed files with 266 additions and 749 deletions
@ -1,173 +0,0 @@ |
|||||
<template> |
|
||||
<div class="benefits-wrapper"> |
|
||||
<div class="carousel"> |
|
||||
<EffectFade :list="benefits?.fileList ?? []"> |
|
||||
<template v-slot="{ item }"> |
|
||||
<div class="banner-wrapper"> |
|
||||
<img class="banner" :src="config.sourceUrl + item" alt="" /> |
|
||||
</div> |
|
||||
</template> |
|
||||
</EffectFade> |
|
||||
</div> |
|
||||
<div class="right"> |
|
||||
<h1 class="title">{{ switchLanguage(benefits, 'title') }}</h1> |
|
||||
<ScrollView class="intro-scroll" scrollbar> |
|
||||
<p class="intro">{{ switchLanguage(benefits, 'content') }}</p> |
|
||||
</ScrollView> |
|
||||
<div class="right-bottom"> |
|
||||
<div class="group"> |
|
||||
<ThumbQRCode v-for="item of qr" :url="config.sourceUrl + item.fileUrl" :title="switchLanguage(item, 'name')" :key="item.name" /> |
|
||||
</div> |
|
||||
<div class="bottom-right" @click="showLoginDialog = true"> |
|
||||
<img src="../../assets/images/member/phone-login.png" alt="" class="phone-icon" /> |
|
||||
<div class="line"></div> |
|
||||
<div class="text-box"> |
|
||||
<p class="enter">点此进入</p> |
|
||||
<p class="text">手机号注册</p> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<Teleport to="body"> |
|
||||
<Transition enter-active-class="animate__animated animate__zoomIn" leave-active-class="animate__animated animate__zoomOut"> |
|
||||
<LoginByPhone @close="showLoginDialog = false" v-if="showLoginDialog" /> |
|
||||
</Transition> |
|
||||
</Teleport> |
|
||||
|
|
||||
<LoginError @close="showLoginError = false" v-if="showLoginError" /> |
|
||||
</template> |
|
||||
|
|
||||
<script setup> |
|
||||
import { ref, computed, defineAsyncComponent } from 'vue' |
|
||||
import { storeToRefs } from 'pinia' |
|
||||
import { useStore } from '@/store/root' |
|
||||
import EffectFade from '@/components/EffectFade/EffectFade.vue' |
|
||||
import ScrollView from '@/base/ScrollView/ScrollView.vue' |
|
||||
import ThumbQRCode from '@/base/ThumbQRCode/ThumbQRCode.vue' |
|
||||
const LoginByPhone = defineAsyncComponent(() => import('@/components/LoginByPhone/LoginByPhone.vue')) |
|
||||
const LoginError = defineAsyncComponent(() => import('@/components/LoginError/LoginError.vue')) |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
benefits: Object |
|
||||
}) |
|
||||
|
|
||||
const store = useStore() |
|
||||
const { config } = storeToRefs(store) |
|
||||
const qr = computed(() => props.benefits.qrFileList ?? []) |
|
||||
|
|
||||
const showLoginDialog = ref(false) |
|
||||
|
|
||||
const showLoginError = ref(false) |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.benefits-wrapper { |
|
||||
width: 870px; |
|
||||
left: 72px; |
|
||||
top: 344px; |
|
||||
background: rgba(255, 255, 255, 0.4); |
|
||||
box-shadow: inset 1px 0px 0px #ffffff; |
|
||||
border-radius: 12px; |
|
||||
margin-left: 170px; |
|
||||
margin-top: 58px; |
|
||||
padding-bottom: 56px; |
|
||||
|
|
||||
:deep(.swiper-pagination-bullet) { |
|
||||
width: 16px !important; |
|
||||
height: 3px !important; |
|
||||
background: rgba(0, 0, 0, 0.1); |
|
||||
border-radius: 3px !important; |
|
||||
opacity: inherit !important; |
|
||||
&.swiper-pagination-bullet-active { |
|
||||
background: #f1b33e; |
|
||||
border-radius: 3px !important; |
|
||||
} |
|
||||
} |
|
||||
.carousel { |
|
||||
flex-shrink: 0; |
|
||||
width: 870px; |
|
||||
height: 490px; |
|
||||
margin-right: 56px; |
|
||||
background: #ffffff; |
|
||||
border-radius: 8px; |
|
||||
overflow: hidden; |
|
||||
} |
|
||||
.banner { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
object-fit: cover; |
|
||||
} |
|
||||
} |
|
||||
.right-bottom { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
padding-right: 56px; |
|
||||
margin-left: 56px; |
|
||||
} |
|
||||
.bottom-right { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
width: 328px; |
|
||||
height: 146px; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.03), inset 0px -4px 0px rgba(177, 189, 220, 0.1); |
|
||||
border-radius: 8px; |
|
||||
.phone-icon { |
|
||||
width: 48px; |
|
||||
height: 48px; |
|
||||
} |
|
||||
.line { |
|
||||
width: 1px; |
|
||||
height: 38px; |
|
||||
left: 134px; |
|
||||
top: 54px; |
|
||||
background: rgba(0, 0, 0, 0.1); |
|
||||
margin: 0 26px; |
|
||||
} |
|
||||
.enter { |
|
||||
font-weight: 700; |
|
||||
font-size: 16px; |
|
||||
color: rgba(0, 0, 0, 0.4); |
|
||||
padding-bottom: 4px; |
|
||||
font-family: 'font_bold'; |
|
||||
} |
|
||||
.text { |
|
||||
font-weight: 700; |
|
||||
font-size: 20px; |
|
||||
text-align: center; |
|
||||
font-family: 'font_bold'; |
|
||||
color: rgba(0, 0, 0, 0.6); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
padding-top: 48px; |
|
||||
font-weight: 700; |
|
||||
font-family: 'font_bold'; |
|
||||
font-size: 24px; |
|
||||
line-height: 28px; |
|
||||
color: rgba(0, 0, 0, 0.8); |
|
||||
padding-bottom: 32px; |
|
||||
margin-left: 56px; |
|
||||
} |
|
||||
|
|
||||
.intro-scroll { |
|
||||
position: relative; |
|
||||
height: 156px; |
|
||||
overflow: hidden; |
|
||||
margin-left: 56px; |
|
||||
margin-right: 34px; |
|
||||
padding-right: 16px; |
|
||||
margin-bottom: 67px; |
|
||||
.intro { |
|
||||
font-weight: 400; |
|
||||
font-size: 14px; |
|
||||
line-height: 200%; |
|
||||
text-align: justify; |
|
||||
color: rgba(0, 0, 0, 0.6); |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
||||
@ -0,0 +1,121 @@ |
|||||
|
<template> |
||||
|
<div class="benefits-wrapper"> |
||||
|
<div class="carousel"> |
||||
|
<EffectFade :list="data?.fileList ?? []"> |
||||
|
<template v-slot="{ item }"> |
||||
|
<div class="banner-wrapper"> |
||||
|
<img class="banner" :src="config.sourceUrl + item" alt="" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
</EffectFade> |
||||
|
</div> |
||||
|
<div class="right"> |
||||
|
<h1 class="title">{{ switchLanguage(data, 'title') }}</h1> |
||||
|
<ScrollView class="intro-scroll" scrollbar> |
||||
|
<p class="intro"> |
||||
|
{{ switchLanguage(data, 'content') }} |
||||
|
</p> |
||||
|
</ScrollView> |
||||
|
<div class="qrcodeWrapper"> |
||||
|
<ThumbQRCode class="item" v-for="item of qr" :url="config.sourceUrl + item.fileUrl" :title="switchLanguage(item, 'name')" :key="item.name" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, computed, defineAsyncComponent } from 'vue' |
||||
|
import { storeToRefs } from 'pinia' |
||||
|
import { useStore } from '@/store/root' |
||||
|
import EffectFade from '@/components/EffectFade/EffectFade.vue' |
||||
|
import ScrollView from '@/base/ScrollView/ScrollView.vue' |
||||
|
import ThumbQRCode from '@/base/ThumbQRCode/ThumbQRCode.vue' |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
data: Object |
||||
|
}) |
||||
|
|
||||
|
const store = useStore() |
||||
|
const { config } = storeToRefs(store) |
||||
|
const qr = computed(() => props.data.qrFileList ?? []) |
||||
|
|
||||
|
const showLoginDialog = ref(false) |
||||
|
|
||||
|
const showLoginError = ref(false) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.benefits-wrapper { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
width: 100%; |
||||
|
flex: 1; |
||||
|
align-items: center; |
||||
|
padding-top: 48px; |
||||
|
|
||||
|
.carousel { |
||||
|
flex-shrink: 0; |
||||
|
width: 944px; |
||||
|
height: 548px; |
||||
|
|
||||
|
overflow: hidden; |
||||
|
:deep(.swiper) { |
||||
|
overflow: visible; |
||||
|
.swiper-pagination { |
||||
|
bottom: -16px; |
||||
|
.swiper-pagination-bullet { |
||||
|
width: 34px !important; |
||||
|
height: 4px !important; |
||||
|
background: rgba(0, 0, 0, 0.6); |
||||
|
border-radius: 6px !important; |
||||
|
opacity: inherit !important; |
||||
|
margin: 0; |
||||
|
&.swiper-pagination-bullet-active { |
||||
|
background: #ffffff; |
||||
|
border-radius: 6px !important; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.banner { |
||||
|
width: 944px; |
||||
|
height: 532px; |
||||
|
border-radius: 8px; |
||||
|
object-fit: cover; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.qrcodeWrapper { |
||||
|
display: flex; |
||||
|
margin-left: 68px; |
||||
|
.item { |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
} |
||||
|
.title { |
||||
|
padding-top: 32px; |
||||
|
padding-left: 68px; |
||||
|
font-weight: 700; |
||||
|
font-size: 28px; |
||||
|
line-height: 150%; |
||||
|
color: rgba(0, 0, 0, 0.8); |
||||
|
} |
||||
|
|
||||
|
.intro-scroll { |
||||
|
position: relative; |
||||
|
height: 250px; |
||||
|
overflow: hidden; |
||||
|
margin-left: 68px; |
||||
|
margin-right: 31px; |
||||
|
padding-right: 31px; |
||||
|
margin-bottom: 33px; |
||||
|
margin-top: 32px; |
||||
|
.intro { |
||||
|
font-weight: 400; |
||||
|
font-size: 16px; |
||||
|
line-height: 200%; |
||||
|
text-align: justify; |
||||
|
color: rgba(0, 0, 0, 0.6); |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,82 @@ |
|||||
|
<template> |
||||
|
<div class="tabs" v-if="sidebarList.find(({ path }) => path === $route.path)"> |
||||
|
<div :class="['item', tab.path === $route.path ? 'active' : '']" v-for="tab of sidebarList" :key="tab.title" @click="goPage(tab)"> |
||||
|
<div class="icon"><img :src="tab.icon" /></div> |
||||
|
<div class="title">{{ switchLanguage(tab, 'title') }}</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { useStore } from '@/store/root' |
||||
|
import { storeToRefs } from 'pinia' |
||||
|
import { useRouter } from 'vue-router' |
||||
|
const router = useRouter() |
||||
|
const store = useStore() |
||||
|
const { sidebarList } = storeToRefs(store) |
||||
|
const goPage = item => { |
||||
|
store.SET_SELECTED_MODULE(item.title) |
||||
|
router.push(item.path) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.tabs { |
||||
|
position: fixed; |
||||
|
top: 400px; |
||||
|
left: 68px; |
||||
|
right: 68px; |
||||
|
display: flex; |
||||
|
.item { |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
flex: 1; |
||||
|
height: 170px; |
||||
|
.icon { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
height: 97px; |
||||
|
background: rgba(255, 255, 255, 0.4); |
||||
|
border-radius: 24px; |
||||
|
img { |
||||
|
width: 80px; |
||||
|
height: 80px; |
||||
|
} |
||||
|
} |
||||
|
.title { |
||||
|
font-weight: 700; |
||||
|
font-size: 18px; |
||||
|
line-height: 21px; |
||||
|
text-align: center; |
||||
|
color: rgba(0, 0, 0, 0.4); |
||||
|
margin-top: 12px; |
||||
|
} |
||||
|
&.active { |
||||
|
.icon { |
||||
|
background: #ffffff; |
||||
|
} |
||||
|
.title { |
||||
|
color: rgba(0, 0, 0, 0.8); |
||||
|
} |
||||
|
&::after { |
||||
|
content: ''; |
||||
|
display: block; |
||||
|
position: absolute; |
||||
|
width: 124px; |
||||
|
height: 6px; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
margin: auto; |
||||
|
background: linear-gradient(113.71deg, #435acd 0%, #749cf3 100%); |
||||
|
border-radius: 2px 2px 0px 0px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.item + .item { |
||||
|
margin-left: 24px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,21 @@ |
|||||
|
<template> |
||||
|
<View long> |
||||
|
<CarouselWithIntro :data="mall" /> |
||||
|
</View> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref } from 'vue' |
||||
|
import { getMallInfoList } from '@/http/api' |
||||
|
import View from '@/layouts/View.vue' |
||||
|
import CarouselWithIntro from '@/components/CarouselWithIntro/CarouselWithIntro.vue' |
||||
|
|
||||
|
const mall = ref({}) |
||||
|
getMallInfoList().then(({ data }) => { |
||||
|
if (!data.title) data.title = '商场介绍' |
||||
|
mall.value = data |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
</style> |
||||
@ -1,318 +1,21 @@ |
|||||
<template> |
<template> |
||||
<View title="热门电影" sub-title="Popular Movies"> |
|
||||
<div class="content"> |
|
||||
<div class="movie-left"> |
|
||||
<div class="carousel"> |
|
||||
<EffectFade :list="banner"> |
|
||||
<template v-slot="{ item }"> |
|
||||
<div class="banner-wrapper"> |
|
||||
<img :src="config.sourceUrl + item" class="banner" alt="" /> |
|
||||
</div> |
|
||||
</template> |
|
||||
</EffectFade> |
|
||||
</div> |
|
||||
|
|
||||
<div class="top-right"> |
|
||||
<div class="go"> |
|
||||
<img src="../../assets/images/fly.png" class="fly" alt="" /> |
|
||||
<div class="text-wrapper"> |
|
||||
<p class="en">GO HERE!</p> |
|
||||
<p class="text">去这里!</p> |
|
||||
</div> |
|
||||
</div> |
|
||||
<h1 class="title">{{ switchLanguage(cinema, 'shopName') }}</h1> |
|
||||
</div> |
|
||||
</div> |
|
||||
<ScrollView class="intro-scroll" scrollbar :list="cinema.content"> |
|
||||
<p class="intro"> |
|
||||
欧时力(香港)集团全权代理意大利品牌欧时力(OCHIRLY),并组建欧时力(中国)有限公司,全权负责OCHIRLY在大中华区的品牌经营。欧时力自1999年进入中国市场以来,欧时力以前所未有的速度在中国市场发展壮大。在短短的两、三年间,迅速于中国60多个一、二类主要消费城市的160余家加盟店以及专柜年销售额达到2.5亿。销售业绩评效均名列前茅,整体业绩不断上扬!在女装市场享有一定的知名度和美誉度。欧时力(香港)集团全权代理意大利品牌欧时力(OCHIRLY),并组建欧时力(中国)有限公司,全权负责OCHIRLY在大中华区的品牌经营。欧时力自1999年进入中国市场以来,欧时力以前所未有的速度在中国市场发展壮大。在短短的两、三年间,迅速于中国60多个一、二类主要消费城市的160余家加盟店以及专柜年销售额达到2.5亿在短短的两、三年间,迅速于中国60多个一、二类主要消费城市的160余家加盟店以及专柜年销售额达到2.5亿在短短的两、三年间,迅速于中 |
|
||||
</p> |
|
||||
</ScrollView> |
|
||||
<ScrollView class="movie-scroll"> |
|
||||
<TransitionGroup tag="div" name="zoom" class="scroll-content"> |
|
||||
<div class="movie-item" v-for="item of list" @click="handleMovie(item)" :key="item.id"> |
|
||||
<div class="poster-wrapper"> |
|
||||
<img class="poster" :src="item.posterPath" alt="" /> |
|
||||
</div> |
|
||||
<p class="name">{{ item.showName }}</p> |
|
||||
<div class="info">{{ item.duration }}{{ $t('fenzhong') }} | {{ item.type }} | {{ item.language }} | {{ item.director }}</div> |
|
||||
<div class="remark"> |
|
||||
<span>{{ $t('rate') }}</span> |
|
||||
{{ item.remark }} |
|
||||
</div> |
|
||||
<div class="price"> |
|
||||
<div class="price-num">¥<i>36</i>起</div> |
|
||||
<div class="buy">{{ $t('ticket') }}</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</TransitionGroup> |
|
||||
</ScrollView> |
|
||||
</div> |
|
||||
|
<View long> |
||||
|
<CarouselWithIntro :data="mall" /> |
||||
</View> |
</View> |
||||
<Transition enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut"> |
|
||||
<MovieDetail :movie="movie" @close="showDetail = false" v-if="showDetail" /> |
|
||||
</Transition> |
|
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
import { computed, ref } from 'vue' |
|
||||
import { storeToRefs } from 'pinia' |
|
||||
import { useStore } from '@/store/root' |
|
||||
import { list } from './mock' |
|
||||
|
import { ref } from 'vue' |
||||
import { getCinemaInfo } from '@/http/api' |
import { getCinemaInfo } from '@/http/api' |
||||
import View from '@/layouts/View.vue' |
import View from '@/layouts/View.vue' |
||||
import EffectFade from '@/components/EffectFade/EffectFade.vue' |
|
||||
import ScrollView from '@/base/ScrollView/ScrollView.vue' |
|
||||
import MovieDetail from '@/components/MovieDetail/MovieDetail.vue' |
|
||||
|
|
||||
const store = useStore() |
|
||||
const { config, shopList } = storeToRefs(store) |
|
||||
|
import CarouselWithIntro from '@/components/CarouselWithIntro/CarouselWithIntro.vue' |
||||
|
|
||||
const cinema = ref({}) |
|
||||
const banner = computed(() => cinema.value?.doorMaterialList ?? []) |
|
||||
getCinemaInfo(({ data }) => { |
|
||||
const { cinemaCode = '' } = data |
|
||||
cinema.value = shopList.value.find(item => item.shopId === cinemaCode) ?? {} |
|
||||
|
const mall = ref({}) |
||||
|
getCinemaInfo().then(({ data }) => { |
||||
|
console.log(data) |
||||
|
mall.value = data |
||||
}) |
}) |
||||
|
|
||||
const showDetail = ref(false) |
|
||||
const movie = ref({}) |
|
||||
function handleMovie(item) { |
|
||||
movie.value = item |
|
||||
showDetail.value = true |
|
||||
} |
|
||||
</script> |
</script> |
||||
|
|
||||
<style lang="scss" scoped> |
<style lang="scss" scoped> |
||||
.content { |
|
||||
width: 870px; |
|
||||
height: 1504px; |
|
||||
margin-left: 170px; |
|
||||
margin-top: 58px; |
|
||||
background: rgba(255, 255, 255, 0.4); |
|
||||
border-radius: 12px; |
|
||||
} |
|
||||
.flex { |
|
||||
display: flex; |
|
||||
} |
|
||||
.movie-left { |
|
||||
display: flex; |
|
||||
position: relative; |
|
||||
border-radius: 12px; |
|
||||
margin-bottom: 32px; |
|
||||
.go { |
|
||||
position: relative; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
width: 282px; |
|
||||
height: 80px; |
|
||||
background: linear-gradient(90deg, #f6a62c 0%, #ffbc3f 100%); |
|
||||
font-weight: 700; |
|
||||
font-family: 'font_bold'; |
|
||||
color: #ffffff; |
|
||||
margin-top: 32px; |
|
||||
border-radius: 53px; |
|
||||
&::before { |
|
||||
position: absolute; |
|
||||
content: ''; |
|
||||
top: 25px; |
|
||||
left: 105px; |
|
||||
width: 1px; |
|
||||
height: 30px; |
|
||||
background: rgba(255, 255, 255, 0.2); |
|
||||
} |
|
||||
.fly { |
|
||||
width: 40px; |
|
||||
margin: 0 40px; |
|
||||
} |
|
||||
.en { |
|
||||
font-size: 20px; |
|
||||
} |
|
||||
.text { |
|
||||
font-size: 16px; |
|
||||
} |
|
||||
} |
|
||||
:deep(.swiper) { |
|
||||
overflow: visible !important; |
|
||||
z-index: auto; |
|
||||
} |
|
||||
:deep(.swiper-pagination) { |
|
||||
right: 32px; |
|
||||
left: auto; |
|
||||
bottom: -15px; |
|
||||
width: auto; |
|
||||
} |
|
||||
:deep(.swiper-pagination-bullet) { |
|
||||
width: 16px !important; |
|
||||
height: 3px !important; |
|
||||
background: rgba(0, 0, 0, 0.1); |
|
||||
border-radius: 3px !important; |
|
||||
opacity: inherit !important; |
|
||||
&.swiper-pagination-bullet-active { |
|
||||
background: #f1b33e; |
|
||||
border-radius: 3px !important; |
|
||||
} |
|
||||
} |
|
||||
.carousel { |
|
||||
flex-shrink: 0; |
|
||||
position: relative; |
|
||||
display: inline-block; |
|
||||
margin-left: 40px; |
|
||||
margin-right: 24px; |
|
||||
width: 500px; |
|
||||
height: 282px; |
|
||||
margin-top: -40px; |
|
||||
background-color: #fff; |
|
||||
border-radius: 10px; |
|
||||
overflow: hidden; |
|
||||
:deep(.stay-tuned) { |
|
||||
height: 200px; |
|
||||
} |
|
||||
} |
|
||||
.banner-wrapper { |
|
||||
width: 500px; |
|
||||
height: 282px; |
|
||||
overflow: hidden; |
|
||||
border-radius: 8px; |
|
||||
background: #ffffff; |
|
||||
.banner { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
object-fit: cover; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
font-weight: 700; |
|
||||
font-size: 24px; |
|
||||
color: rgba(0, 0, 0, 0.8); |
|
||||
font-family: 'font_bold'; |
|
||||
padding-top: 102px; |
|
||||
text-align: right; |
|
||||
padding-right: 40px; |
|
||||
} |
|
||||
} |
|
||||
.intro-scroll { |
|
||||
position: relative; |
|
||||
margin: 0 18px 52px 40px; |
|
||||
padding-right: 16px; |
|
||||
overflow: hidden; |
|
||||
height: 131px; |
|
||||
z-index: 1; |
|
||||
:deep(.bscroll-vertical-scrollbar) { |
|
||||
width: 6px !important; |
|
||||
background: rgba(0, 0, 0, 0.02) !important; |
|
||||
border-radius: 6px !important; |
|
||||
opacity: 1 !important; |
|
||||
.bscroll-indicator { |
|
||||
width: 6px !important; |
|
||||
background: rgba(0, 0, 0, 0.1) !important; |
|
||||
border-radius: 6px !important; |
|
||||
border: none !important; |
|
||||
} |
|
||||
} |
|
||||
.intro { |
|
||||
font-weight: 400; |
|
||||
font-size: 14px; |
|
||||
line-height: 200%; |
|
||||
text-align: justify; |
|
||||
color: rgba(0, 0, 0, 0.6); |
|
||||
} |
|
||||
} |
|
||||
.movie-scroll { |
|
||||
flex: 1; |
|
||||
overflow: hidden; |
|
||||
border-radius: 12px 0 0 12px; |
|
||||
margin-left: 40px; |
|
||||
height: 1103px; |
|
||||
|
|
||||
.scroll-content { |
|
||||
display: grid; |
|
||||
grid-template-columns: repeat(3, 260px); |
|
||||
gap: 36px 8px; |
|
||||
padding-bottom: 36px; |
|
||||
} |
|
||||
|
|
||||
.movie-item { |
|
||||
width: 260px; |
|
||||
height: 600px; |
|
||||
background: #ffffff; |
|
||||
border-radius: 12px; |
|
||||
padding: 4px; |
|
||||
margin-right: 24px; |
|
||||
} |
|
||||
.poster-wrapper { |
|
||||
width: 252px; |
|
||||
height: 380px; |
|
||||
border-radius: 8px; |
|
||||
overflow: hidden; |
|
||||
margin-bottom: 24px; |
|
||||
.poster { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
object-fit: cover; |
|
||||
} |
|
||||
} |
|
||||
.name { |
|
||||
font-weight: 700; |
|
||||
font-size: 20px; |
|
||||
color: rgba(0, 0, 0, 0.8); |
|
||||
@include no-wrap; |
|
||||
padding-bottom: 20px; |
|
||||
padding-left: 24px; |
|
||||
} |
|
||||
.info { |
|
||||
height: 28px; |
|
||||
font-weight: 400; |
|
||||
font-size: 12px; |
|
||||
line-height: 14px; |
|
||||
color: rgba(0, 0, 0, 0.4); |
|
||||
@include more-wrap; |
|
||||
padding-left: 24px; |
|
||||
padding-right: 24px; |
|
||||
margin-bottom: 14px; |
|
||||
white-space: normal; |
|
||||
} |
|
||||
.remark { |
|
||||
font-weight: 700; |
|
||||
color: rgba(0, 0, 0, 0.6); |
|
||||
padding-bottom: 10px; |
|
||||
margin-left: 24px; |
|
||||
margin-right: 24px; |
|
||||
margin-bottom: 16px; |
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.02); |
|
||||
|
|
||||
span { |
|
||||
font-size: 16px; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.price { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
padding-left: 24px; |
|
||||
padding-right: 24px; |
|
||||
color: #f1b33e; |
|
||||
font-weight: 700; |
|
||||
font-family: 'font_bold'; |
|
||||
.price-num { |
|
||||
font-size: 16px; |
|
||||
i { |
|
||||
font-size: 32px; |
|
||||
padding: 0 4px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.buy { |
|
||||
width: 98px; |
|
||||
height: 38px; |
|
||||
background: linear-gradient(90deg, #f6a62c 0%, #ffbc3f 100%); |
|
||||
border-radius: 8px; |
|
||||
line-height: 38px; |
|
||||
text-align: center; |
|
||||
font-weight: 700; |
|
||||
font-size: 14px; |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
} |
|
||||
</style> |
</style> |
||||
|
|||||
@ -1,227 +1,20 @@ |
|||||
<template> |
<template> |
||||
<View class="bef" title="泊车缴费" sub-title="parking payment"> |
|
||||
<Tabs class="width" @click="handleTab" :list="list" /> |
|
||||
<div class="carousel"> |
|
||||
<EffectFade :list="banners"> |
|
||||
<template v-slot="{ item }"> |
|
||||
<div class="banner-wrapper"> |
|
||||
<img :src="config.sourceUrl + item" class="banner" alt="" /> |
|
||||
</div> |
|
||||
</template> |
|
||||
</EffectFade> |
|
||||
</div> |
|
||||
<PlateInput @confirm="confirm" @handle-energy="handleEnergy" :search-methods="searchMethods" :license="license" :needsEnergy="needsEnergy" /> |
|
||||
<PlateKeyboard @del="del" @handle-keyboard="handleKeyboard" :search-methods="searchMethods" /> |
|
||||
<div class="parking-info"> |
|
||||
<h1 class="title">{{ switchLanguage(parkingInfo, 'title') }}</h1> |
|
||||
<ScrollView class="intro-scroll" scrollbar :list="parkingInfo.content"> |
|
||||
<p class="intro">{{ switchLanguage(parkingInfo, 'content') }}</p> |
|
||||
</ScrollView> |
|
||||
</div> |
|
||||
|
<View long> |
||||
|
<CarouselWithIntro :data="park" /> |
||||
</View> |
</View> |
||||
<Transition enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut"> |
|
||||
<CarInfo v-if="showCarInfo" @close="showCarInfo = false" /> |
|
||||
</Transition> |
|
||||
</template> |
</template> |
||||
|
|
||||
<script setup> |
<script setup> |
||||
import Message from '@/base/Message/Message' |
|
||||
import ScrollView from '@/base/ScrollView/ScrollView.vue' |
|
||||
import EffectFade from '@/components/EffectFade/EffectFade.vue' |
|
||||
import PlateInput from '@/components/PlateInput/PlateInput.vue' |
|
||||
import PlateKeyboard from '@/components/PlateKeyboard/PlateKeyboard.vue' |
|
||||
import Tabs from '@/components/Tabs/Tabs.vue' |
|
||||
|
import { ref } from 'vue' |
||||
import { getParkingList } from '@/http/api' |
import { getParkingList } from '@/http/api' |
||||
import View from '@/layouts/View.vue' |
import View from '@/layouts/View.vue' |
||||
import { useStore } from '@/store/root' |
|
||||
import { isLicensePlate, isUppercaseWord, isZhWord } from '@/utils/utils' |
|
||||
import { storeToRefs } from 'pinia' |
|
||||
import { computed, defineAsyncComponent, ref, watch } from 'vue' |
|
||||
import { list } from './tabs' |
|
||||
import Shop from '@/utils/Class/Shop' |
|
||||
import { useRouter } from 'vue-router' |
|
||||
const CarInfo = defineAsyncComponent(() => import('@/components/CarInfo/CarInfo.vue')) |
|
||||
|
import CarouselWithIntro from '@/components/CarouselWithIntro/CarouselWithIntro.vue' |
||||
|
|
||||
const NOT_ENERGY_PLATE = 7 //非能源车牌长度 |
|
||||
const ENERGY_PLATE = 8 //能源车牌长度 |
|
||||
const SPACE_MAX_LENGTH = 5 //车位最大允许长度 |
|
||||
|
|
||||
const router = useRouter() |
|
||||
const store = useStore() |
|
||||
const { config, currentBuildingFloorsList } = storeToRefs(store) |
|
||||
|
|
||||
const tabIdx = ref(0) |
|
||||
const needsEnergy = computed(() => tabIdx.value === 0) |
|
||||
const searchMethods = computed(() => (tabIdx.value === 0 ? '车牌' : '车位')) |
|
||||
function handleTab(index) { |
|
||||
tabIdx.value = index |
|
||||
license.value = index === 0 ? ['苏', 'A'] : [] |
|
||||
} |
|
||||
|
|
||||
const isEnergy = ref(false) |
|
||||
const license = ref(['苏', 'A']) |
|
||||
const licenseToString = computed(() => license.value.join('')) |
|
||||
function handleKeyboard(item) { |
|
||||
if (license.value.length === 1 && isZhWord(item)) { |
|
||||
license.value[0] = item |
|
||||
return |
|
||||
} |
|
||||
|
|
||||
if (tabIdx.value === 0) { |
|
||||
if ( |
|
||||
(!isEnergy.value && license.value.length >= NOT_ENERGY_PLATE) || |
|
||||
(isEnergy.value && license.value.length >= ENERGY_PLATE) || |
|
||||
(license.value.length === 0 && !isZhWord(item)) || |
|
||||
(license.value.length === 1 && !isUppercaseWord(item)) || |
|
||||
(license.value.length >= 2 && license.value.length < 6 && isZhWord(item)) |
|
||||
) { |
|
||||
return |
|
||||
} |
|
||||
} else { |
|
||||
if (license.value.length >= SPACE_MAX_LENGTH) return |
|
||||
} |
|
||||
|
|
||||
license.value.push(item) |
|
||||
} |
|
||||
function del() { |
|
||||
license.value.pop() |
|
||||
} |
|
||||
|
|
||||
//点击能源输入框 |
|
||||
function handleEnergy(flag) { |
|
||||
isEnergy.value = flag |
|
||||
license.value.length >= ENERGY_PLATE && license.value.pop() |
|
||||
} |
|
||||
|
|
||||
//找车 |
|
||||
function confirm() { |
|
||||
if (tabIdx.value === 0) { |
|
||||
//TODO |
|
||||
Message({ text: '抱歉暂时无法使用车牌找车', type: 'success' }) |
|
||||
} else { |
|
||||
//车位 |
|
||||
const info = window.Map_QM.pathPark({ shopNum: license.value }) |
|
||||
if (info?.node?.length) { |
|
||||
const floorName = currentBuildingFloorsList.value.filter(item => item.order === info.floor)?.[0]?.name |
|
||||
const shop = new Shop({ name: license.value, floorOrder: info.floor, floorName, logoPath: '/static/img/tcc/png', yaxis: info.node }) |
|
||||
store.SET_SHOP(shop) |
|
||||
router.push('/nav') |
|
||||
} else { |
|
||||
Message({ text: `暂未查到车位信息`, type: 'success' }) |
|
||||
license.value = [] |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
watch( |
|
||||
license, |
|
||||
newVal => { |
|
||||
newVal.length === (isEnergy.value ? ENERGY_PLATE : NOT_ENERGY_PLATE) && !isLicensePlate(licenseToString.value) && Message({ text: '车牌错误', type: 'success' }) |
|
||||
}, |
|
||||
{ |
|
||||
deep: true |
|
||||
} |
|
||||
) |
|
||||
|
|
||||
const parkingInfo = ref({}) |
|
||||
const banners = computed(() => parkingInfo.value.fileList ?? []) |
|
||||
|
const park = ref({}) |
||||
getParkingList().then(({ data }) => { |
getParkingList().then(({ data }) => { |
||||
parkingInfo.value = data ?? {} |
|
||||
|
park.value = data |
||||
}) |
}) |
||||
|
|
||||
const showCarInfo = ref(false) |
|
||||
</script> |
</script> |
||||
|
|
||||
<style lang="scss" scoped> |
<style lang="scss" scoped> |
||||
.flex { |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
} |
|
||||
.width { |
|
||||
position: absolute !important; |
|
||||
top: 214px !important; |
|
||||
left: 170px !important; |
|
||||
width: 468px !important; |
|
||||
height: 88px !important; |
|
||||
} |
|
||||
.carousel { |
|
||||
position: relative; |
|
||||
width: 870px; |
|
||||
height: 490px; |
|
||||
margin-left: 170px; |
|
||||
margin-top: 58px; |
|
||||
margin-bottom: 80px; |
|
||||
:deep(.swiper) { |
|
||||
overflow: visible !important; |
|
||||
z-index: auto; |
|
||||
} |
|
||||
:deep(.swiper-pagination) { |
|
||||
bottom: -24px; |
|
||||
} |
|
||||
:deep(.swiper-pagination-bullet) { |
|
||||
width: 16px !important; |
|
||||
height: 3px !important; |
|
||||
background: rgba(0, 0, 0, 0.1); |
|
||||
border-radius: 3px !important; |
|
||||
opacity: inherit !important; |
|
||||
&.swiper-pagination-bullet-active { |
|
||||
background: #f1b33e; |
|
||||
border-radius: 3px !important; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.banner-wrapper { |
|
||||
width: 870px; |
|
||||
height: 490px; |
|
||||
overflow: hidden; |
|
||||
border-radius: 8px; |
|
||||
background: #ffffff; |
|
||||
.banner { |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
object-fit: cover; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.parking-info { |
|
||||
margin-left: 170px; |
|
||||
margin-right: 40px; |
|
||||
background: rgba(255, 255, 255, 0.4); |
|
||||
border-radius: 12px; |
|
||||
height: 532px; |
|
||||
|
|
||||
.title { |
|
||||
padding: 48px 0 32px 56px; |
|
||||
font-weight: 700; |
|
||||
font-size: 24px; |
|
||||
color: rgba(0, 0, 0, 0.8); |
|
||||
font-family: 'font_bold'; |
|
||||
} |
|
||||
|
|
||||
.intro-scroll { |
|
||||
position: relative; |
|
||||
margin: 0 34px 0 56px; |
|
||||
overflow: hidden; |
|
||||
height: 372px; |
|
||||
:deep(.bscroll-vertical-scrollbar) { |
|
||||
width: 6px !important; |
|
||||
background: rgba(0, 0, 0, 0.02) !important; |
|
||||
border-radius: 6px !important; |
|
||||
opacity: 1 !important; |
|
||||
.bscroll-indicator { |
|
||||
width: 6px !important; |
|
||||
background: rgba(0, 0, 0, 0.1) !important; |
|
||||
border-radius: 6px !important; |
|
||||
border: none !important; |
|
||||
} |
|
||||
} |
|
||||
.intro { |
|
||||
font-weight: 400; |
|
||||
font-size: 14px; |
|
||||
line-height: 200%; |
|
||||
text-align: justify; |
|
||||
color: rgba(0, 0, 0, 0.6); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
</style> |
||||
|
|||||
Loading…
Reference in new issue