@ -0,0 +1,34 @@ |
|||||
|
{ |
||||
|
"code": 200, |
||||
|
"msg": "操作成功", |
||||
|
"data": [ |
||||
|
{ |
||||
|
"regionCode": "mPfaxPdRDVg6CLhdyiIUT", |
||||
|
"regionName": "SKP-S", |
||||
|
"regionNameEn": "SKP-S", |
||||
|
"regionNameJa": "", |
||||
|
"regionNameOl": "" |
||||
|
}, |
||||
|
{ |
||||
|
"regionCode": "L-qsFUgjr8v2vTTpBGVGF", |
||||
|
"regionName": "美食大道", |
||||
|
"regionNameEn": "美食大道英文", |
||||
|
"regionNameJa": "", |
||||
|
"regionNameOl": "" |
||||
|
}, |
||||
|
{ |
||||
|
"regionCode": "N7jMkq7sak-vKNK9rdH7Z", |
||||
|
"regionName": "K大道", |
||||
|
"regionNameEn": "K大道英文", |
||||
|
"regionNameJa": "", |
||||
|
"regionNameOl": "" |
||||
|
}, |
||||
|
{ |
||||
|
"regionCode": "5LD1gMoB4eZoMmIFe0dug", |
||||
|
"regionName": "SKP", |
||||
|
"regionNameEn": "SKP", |
||||
|
"regionNameJa": "", |
||||
|
"regionNameOl": "" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
After Width: | Height: | Size: 391 B |
|
After Width: | Height: | Size: 918 B |
|
After Width: | Height: | Size: 450 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 476 B |
|
After Width: | Height: | Size: 476 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 947 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 983 B |
|
After Width: | Height: | Size: 654 B |
|
After Width: | Height: | Size: 681 B |
|
After Width: | Height: | Size: 571 B |
|
After Width: | Height: | Size: 478 B |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 975 B |
@ -0,0 +1,60 @@ |
|||||
|
<template> |
||||
|
<transition appear enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut"> |
||||
|
<div class="global-masker" @click.self="handleClick"> |
||||
|
<div class="bg-img" @click.self="handleClick" /> |
||||
|
<slot class="mask-content"></slot> |
||||
|
</div> |
||||
|
</transition> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue' |
||||
|
defineProps({ |
||||
|
type: { |
||||
|
type: Number, |
||||
|
default: 0 |
||||
|
} |
||||
|
}) |
||||
|
const emit = defineEmits(['click']) |
||||
|
const flag = ref(true) |
||||
|
function handleClick() { |
||||
|
flag.value = false |
||||
|
const timerId = setTimeout(() => { |
||||
|
clearTimeout(timerId) |
||||
|
emit('click') |
||||
|
}, 20) |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.global-masker { |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
z-index: 9900; |
||||
|
background: rgb(142 144 145 / 50%); |
||||
|
animation-duration: 0.3s; |
||||
|
backdrop-filter: blur(50px); |
||||
|
.bg-img { |
||||
|
position: absolute; |
||||
|
z-index: 0; |
||||
|
// background: rgba(0, 0, 0, 0.3) url('@/assets/images/home/inner_bgNormal.jpg'); |
||||
|
width: 100vw; |
||||
|
height: 100vh; |
||||
|
// backdrop-filter: blur(30px); |
||||
|
filter: blur(0); |
||||
|
} |
||||
|
.blur-wrapper { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
z-index: 9901; |
||||
|
} |
||||
|
.mask-content { |
||||
|
z-index: 9902; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,401 @@ |
|||||
|
<template> |
||||
|
<transition appear enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__fadeOut"> |
||||
|
<masker @click="close"> |
||||
|
<transition |
||||
|
appear |
||||
|
:enter-active-class="'animate__animated animate__fadeInUp'" |
||||
|
leave-active-class="animate__animated animate__zoomOut" |
||||
|
> |
||||
|
<div class="shop-detail-wrapper"> |
||||
|
<div class="intro-container"> |
||||
|
<!-- 图片 --> |
||||
|
<div v-if="false" class="carousel"> |
||||
|
<swiper |
||||
|
:modules="modules" |
||||
|
:autoplay="{ |
||||
|
delay: 5000 |
||||
|
}" |
||||
|
:observer="true" |
||||
|
:observe-parents="true" |
||||
|
:effect="'fade'" |
||||
|
:centered-slides="true" |
||||
|
:pagination="{ el: '.detail' }" |
||||
|
:dynamic-bullets="true" |
||||
|
> |
||||
|
<swiper-slide v-for="(item, index) in shop.doorMaterialList" :key="index" class="slide"> |
||||
|
<img :src="item" class="banner" /> |
||||
|
</swiper-slide> |
||||
|
</swiper> |
||||
|
<img v-if="!shop.doorMaterialList?.length" src="../../assets/images/empty_big.svg" class="banner no-data" alt="" /> |
||||
|
<div class="swiper-pagination detail"></div> |
||||
|
</div> |
||||
|
<!-- logo 名称 属性--> |
||||
|
<div class="name-wrapper"> |
||||
|
<div class="logo-wrapper"> |
||||
|
<img |
||||
|
v-if="shop.logoUrl" |
||||
|
class="shop-logo" |
||||
|
:src="shop.logoUrl.search(config.sourceUrl) >= 0 ? shop.logoUrl : config.sourceUrl + shop.logoUrl" |
||||
|
alt="" |
||||
|
/> |
||||
|
<img v-else class="shop-logo" src="@/assets/images/empty_small.svg" alt="" /> |
||||
|
</div> |
||||
|
<div class="marquee-wrapper"> |
||||
|
<span v-if="marqueesRef?.state?.duration === 0" style="width: 100%" class="name">{{ |
||||
|
switchLanguage(shop, 'shopName') |
||||
|
}}</span> |
||||
|
|
||||
|
<marquees |
||||
|
ref="marqueesRef" |
||||
|
:style="{ height: marqueesRef?.state?.duration === 0 ? '0px' : '' }" |
||||
|
:speed="40" |
||||
|
:delay="0.8" |
||||
|
class="name" |
||||
|
:content="switchLanguage(shop, 'shopName')" |
||||
|
>{{ switchLanguage(shop, 'shopName') }} |
||||
|
</marquees> |
||||
|
</div> |
||||
|
<div class="shop-attr-group"> |
||||
|
<div v-if="shop.industryFatherName" class="working-item"> |
||||
|
<!-- shop.industryUrl --> |
||||
|
<img v-if="shop.industryFatherName" src="@/assets/images/shopDetail/icon_format.svg" alt="" /> |
||||
|
<span class="title">{{ switchLanguage(shop, 'industryFatherName') }}</span> |
||||
|
</div> |
||||
|
<div v-if="shop.houseNumber" class="working-item"> |
||||
|
<img src="../../assets/images/shopDetail/icon_address.svg" alt="" /> |
||||
|
<span class="title">{{ shop.floor + '-' + shop.houseNumber }}</span> |
||||
|
</div> |
||||
|
<div v-if="shop.businessHours" class="working-item"> |
||||
|
<img src="../../assets/images/shopDetail/icon_time.svg" alt="" /> |
||||
|
<span class="title">{{ shop.businessHours }}</span> |
||||
|
</div> |
||||
|
<div v-if="shop.contact" class="working-item"> |
||||
|
<img src="../../assets/images/shopDetail/icon_tel.svg" alt="" /> |
||||
|
<span class="title">{{ shop.contact }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="line"></div> |
||||
|
<!-- 详情 --> |
||||
|
<scroll-view |
||||
|
:list="[switchLanguage(shop, 'intro')]" |
||||
|
class="intro-scroll" |
||||
|
:scrollbar="true" |
||||
|
:pull-up="false" |
||||
|
:refresh-delay="500" |
||||
|
> |
||||
|
<p class="intro" v-html="switchLanguage(shop, 'intro')"></p> |
||||
|
</scroll-view> |
||||
|
<!-- 导航按钮 --> |
||||
|
<div v-if="shop.yaxis" class="go" @click="handleGo"> |
||||
|
<img src="@/assets/images/shopDetail/go.svg" alt="" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- 关闭按钮 --> |
||||
|
<div class="exit" @click="close"> |
||||
|
<img src="@/assets/images/shopDetail/close.svg" class="go_bg" alt="" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</transition> </masker |
||||
|
></transition> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { Autoplay, Pagination, EffectFade } from 'swiper' |
||||
|
import { Swiper, SwiperSlide } from 'swiper/vue' |
||||
|
import 'swiper/css' |
||||
|
import 'swiper/css/pagination' |
||||
|
import 'swiper/css/effect-fade' |
||||
|
import scrollView from '@/base/ScrollView/ScrollView.vue' |
||||
|
import masker from '@/base/Masker/Masker.vue' |
||||
|
import marquees from '@/base/Marquees/Marquees.vue' |
||||
|
import { useRouter } from 'vue-router' |
||||
|
import { useStatistics } from '@/composables/useStatistics' |
||||
|
import { storeToRefs } from 'pinia' |
||||
|
import { useRootStore } from '@/store/root' |
||||
|
import { computed, ref } from 'vue' |
||||
|
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
||||
|
const { switchLanguage } = useSwitchLanguage() |
||||
|
const store = useRootStore() |
||||
|
const { shop, config } = storeToRefs(store) |
||||
|
const router = useRouter() |
||||
|
|
||||
|
const modules = [Autoplay, Pagination, EffectFade] |
||||
|
|
||||
|
const marqueesRef = ref() |
||||
|
const activityList = computed(() => shop.value.activityList) |
||||
|
//关闭窗口 |
||||
|
function close() { |
||||
|
store.SET_SHOW_DETAIL(false) |
||||
|
} |
||||
|
//导航 |
||||
|
function handleGo() { |
||||
|
store.SET_SHOW_DETAIL(false) |
||||
|
store.SET_SHOW_SEARCH(false) |
||||
|
router.push('/nav') |
||||
|
} |
||||
|
|
||||
|
useStatistics({ tag: 'shop', shopCode: shop.value.shopCode }) |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
:deep(.bscroll-vertical-scrollbar) { |
||||
|
z-index: 5 !important; |
||||
|
overflow: visible !important; |
||||
|
// width: 1px !important; |
||||
|
background: rgb(0 0 0 / 6%); |
||||
|
border-radius: 8px; |
||||
|
opacity: 1 !important; |
||||
|
.bscroll-indicator { |
||||
|
// width: 7px !important; |
||||
|
background: #d0b186 !important; |
||||
|
border: none !important; |
||||
|
border-radius: 8px !important; |
||||
|
box-shadow: 0 8px 20px rgb(0 0 0 / 10%); |
||||
|
} |
||||
|
} |
||||
|
:deep(.swiper-pagination-bullet) { |
||||
|
border-radius: 4px !important; |
||||
|
} |
||||
|
.shop-detail-wrapper { |
||||
|
position: relative; |
||||
|
z-index: 9003; |
||||
|
// margin-right: 0px; |
||||
|
// margin-left: 0px; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
width: 864px; |
||||
|
height: 648px; |
||||
|
margin-top: 216px; |
||||
|
margin-left: 528px; |
||||
|
pointer-events: none; |
||||
|
background-color: #fff; |
||||
|
border-radius: 16px; |
||||
|
|
||||
|
& > * { |
||||
|
pointer-events: visible; |
||||
|
} |
||||
|
|
||||
|
// --swiper-theme-color: #d7ba92; |
||||
|
// --swiper-pagination-bullet-width: 28px; |
||||
|
// --swiper-pagination-bullet-height: 4px; |
||||
|
// --swiper-pagination-bullet-inactive-color: rgb(0 0 0 / 60%); |
||||
|
|
||||
|
.intro-container { |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background: linear-gradient(to right, rgb(0 0 0 / 3%) 0%, rgb(0 0 0 / 3%) 37%, #fff 37%, #fff 100%); |
||||
|
border-radius: 16px; |
||||
|
} |
||||
|
|
||||
|
.carousel { |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
display: inline-block; |
||||
|
overflow: hidden; |
||||
|
width: 800px; |
||||
|
height: 450px; |
||||
|
// min-height: 450px; |
||||
|
// max-height: 450px; |
||||
|
margin-top: 0; |
||||
|
margin-left: 0; |
||||
|
// background: #d5d5d5; |
||||
|
background: rgb(255 255 255); |
||||
|
border-radius: 8px; |
||||
|
:deep(.swiper-slide) { |
||||
|
height: 450px; |
||||
|
border-radius: inherit; |
||||
|
} |
||||
|
.banner { |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
width: 100%; |
||||
|
height: inherit; |
||||
|
object-fit: cover; |
||||
|
border-radius: 8px; |
||||
|
&.no-data { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
left: 0; |
||||
|
// width: 300px; |
||||
|
margin: 0 auto; |
||||
|
object-fit: scale-down; |
||||
|
} |
||||
|
} |
||||
|
:deep(.swiper-pagination-bullet) { |
||||
|
border-radius: 59px; |
||||
|
} |
||||
|
.detail { |
||||
|
bottom: 18px; |
||||
|
left: 80%; |
||||
|
display: flex; |
||||
|
width: 20%; |
||||
|
:deep(.swiper-pagination-bullet) { |
||||
|
--swiper-pagination-bullet-width: 0px; |
||||
|
--swiper-pagination-bullet-horizontal-gap: 2px; |
||||
|
|
||||
|
flex-shrink: 0; |
||||
|
&.swiper-pagination-bullet-active { |
||||
|
--swiper-pagination-bullet-horizontal-gap: 4px; |
||||
|
--swiper-pagination-bullet-width: 24px; |
||||
|
} |
||||
|
&:not(.swiper-pagination-bullet-active) { |
||||
|
--swiper-pagination-bullet-horizontal-gap: 4px; |
||||
|
--swiper-pagination-bullet-width: 10px; |
||||
|
--swiper-pagination-bullet-height: 5px; |
||||
|
} |
||||
|
// &.swiper-pagination-bullet-active + span { |
||||
|
// --swiper-pagination-bullet-horizontal-gap: 8px; |
||||
|
// --swiper-pagination-bullet-width: 20px; |
||||
|
// } |
||||
|
} |
||||
|
span + .swiper-pagination-bullet-active { |
||||
|
--swiper-pagination-bullet-horizontal-gap: 4px; |
||||
|
--swiper-pagination-bullet-width: 24px; |
||||
|
} |
||||
|
:not(span + .swiper-pagination-bullet-active) { |
||||
|
--swiper-pagination-bullet-horizontal-gap: 4px; |
||||
|
--swiper-pagination-bullet-width: 2px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.name-wrapper { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
z-index: 1; |
||||
|
width: 320px; |
||||
|
height: 648px; |
||||
|
.logo-wrapper { |
||||
|
position: absolute; |
||||
|
top: 64px; |
||||
|
left: 85px; |
||||
|
z-index: 1; |
||||
|
width: 150px; |
||||
|
height: 150px; |
||||
|
padding: 15px; |
||||
|
background: #fff; |
||||
|
border-radius: 8px; |
||||
|
box-shadow: 0 8px 20px 0 rgb(0 0 0 / 5%); |
||||
|
|
||||
|
img { |
||||
|
width: 120px; |
||||
|
height: 120px; |
||||
|
object-fit: scale-down; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.marquee-wrapper { |
||||
|
overflow: hidden; |
||||
|
width: 280px; |
||||
|
margin-top: 234px; |
||||
|
margin-bottom: 0; |
||||
|
margin-left: 20px; |
||||
|
white-space: nowrap; |
||||
|
.name { |
||||
|
display: inline-block; |
||||
|
height: 36px; |
||||
|
font-size: 28px; |
||||
|
font-family: 'font_bold'; |
||||
|
text-align: center; |
||||
|
color: #534f46; |
||||
|
font-weight: 700; |
||||
|
} |
||||
|
} |
||||
|
.shop-attr-group { |
||||
|
position: absolute; |
||||
|
top: 64px; |
||||
|
left: 368px; |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
width: 448px; |
||||
|
height: 60px; |
||||
|
flex-wrap: wrap; |
||||
|
.working-item { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
min-width: 224px; |
||||
|
height: 22px; |
||||
|
&:nth-child(odd) { |
||||
|
max-width: 224px; |
||||
|
} |
||||
|
&:nth-child(even) { |
||||
|
max-width: 224px; |
||||
|
} |
||||
|
img { |
||||
|
width: 20px; |
||||
|
height: 20px; |
||||
|
padding: 0; |
||||
|
margin-right: 16px; |
||||
|
background: rgb(0 0 0 / 0%); |
||||
|
border-radius: 0; |
||||
|
} |
||||
|
span { |
||||
|
padding-right: 5px; |
||||
|
font-size: 14px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: #615c59; |
||||
|
font-weight: 700; |
||||
|
|
||||
|
@include no-wrap(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.line { |
||||
|
position: absolute; |
||||
|
top: 164px; |
||||
|
right: 64px; |
||||
|
width: 448px; |
||||
|
height: 1px; |
||||
|
background: rgb(0 0 0 / 6%); |
||||
|
} |
||||
|
.intro-scroll { |
||||
|
position: absolute; |
||||
|
top: 205px; |
||||
|
right: 26px; |
||||
|
z-index: 1; |
||||
|
overflow: hidden; |
||||
|
width: 470px; |
||||
|
height: 350px; |
||||
|
padding-right: 16px; |
||||
|
.intro { |
||||
|
font-size: 14px; |
||||
|
font-family: 'font_medium'; |
||||
|
text-align: justify; |
||||
|
white-space: pre-wrap; |
||||
|
color: #615c59; |
||||
|
line-height: 200%; |
||||
|
:deep(img) { |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.go { |
||||
|
position: absolute; |
||||
|
top: 422px; |
||||
|
left: 76px; |
||||
|
z-index: 1; |
||||
|
width: 168px; |
||||
|
} |
||||
|
.exit { |
||||
|
position: absolute; |
||||
|
top: -40px; |
||||
|
right: -40px; |
||||
|
z-index: 1; |
||||
|
width: 100px; |
||||
|
height: 100px; |
||||
|
padding: 26px; |
||||
|
background: var(--w-60, rgb(255 255 255 / 60%)); |
||||
|
border: 2px solid var(--w-100, #fff); |
||||
|
border-radius: 50px; |
||||
|
backdrop-filter: blur(20px); |
||||
|
// margin: auto; |
||||
|
img { |
||||
|
width: 48px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,210 @@ |
|||||
|
<template> |
||||
|
<ul |
||||
|
ref="ulRef" |
||||
|
class="switch-tabs" |
||||
|
:style="{ |
||||
|
width: props.wrapperWidth + 'px', |
||||
|
height: props.wrapperHeight + 'px', |
||||
|
'flex-direction': props.direction! + '', |
||||
|
'background-color': props.background + '' |
||||
|
}" |
||||
|
> |
||||
|
<li |
||||
|
v-for="(item, index) of list" |
||||
|
:key="index" |
||||
|
:style="styles" |
||||
|
class="switch-tab-item" |
||||
|
:class="{ active: index === copyTabIdx }" |
||||
|
@click="switchTab(index)" |
||||
|
> |
||||
|
<!-- :style="{ |
||||
|
filter: 'brightness(0) invert(100%)', |
||||
|
opacity: '1' |
||||
|
}" --> |
||||
|
<img v-if="index === copyTabIdx" :src="item.iconSel" class="intro-icon" alt="" /> |
||||
|
<img v-else :src="item.icon" class="intro-icon" alt="" /> |
||||
|
|
||||
|
<div class="intro-wrapper"> |
||||
|
<span class="intro-name"> |
||||
|
{{ switchLanguage(item, 'name') }} |
||||
|
</span> |
||||
|
<span v-if="item.en" class="intro-name-en"> |
||||
|
{{ item.en }} |
||||
|
</span> |
||||
|
</div> |
||||
|
</li> |
||||
|
<li |
||||
|
ref="scrollBoxRef" |
||||
|
class="scroll-box" |
||||
|
:style="{ |
||||
|
top: props.direction === 'column' ? copyTabIdx * props.height + 'px' : '', |
||||
|
left: props.direction === 'row' ? copyTabIdx * props.width + 'px' : '', |
||||
|
width: props.width + 'px', |
||||
|
height: props.height + 'px' |
||||
|
}" |
||||
|
> |
||||
|
<!-- <svg width="180" height="80" viewBox="0 0 180 80" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path |
||||
|
d="M0 16C0 7.16344 7.16344 0 16 0H164C172.837 0 180 7.16344 180 16V56C180 64.8366 172.837 72 164 72H114.38C112.475 72 110.586 72.3402 108.801 73.0045L95.5162 77.9474C91.9554 79.2724 88.0392 79.287 84.4686 77.9886L70.6491 72.9633C68.8965 72.326 67.046 72 65.1812 72H16C7.16344 72 0 64.8366 0 56V16Z" |
||||
|
fill="url(#paint0_linear_616_449)" |
||||
|
/> |
||||
|
<defs> |
||||
|
<linearGradient id="paint0_linear_616_449" x1="14" y1="4" x2="176.063" y2="22.7587" gradientUnits="userSpaceOnUse"> |
||||
|
<stop :stop-color="gradientColor.startColor" /> |
||||
|
<stop offset="1" :stop-color="gradientColor.endColor" /> |
||||
|
</linearGradient> |
||||
|
</defs> |
||||
|
</svg> --> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
||||
|
import { computed, ref, onMounted, watch, nextTick } from 'vue' |
||||
|
|
||||
|
const { switchLanguage } = useSwitchLanguage() |
||||
|
|
||||
|
type ListItem = { |
||||
|
name: string |
||||
|
en: string |
||||
|
icon: string |
||||
|
iconSel: string |
||||
|
} |
||||
|
type Props = { |
||||
|
list: ListItem[] |
||||
|
wrapperHeight?: number |
||||
|
wrapperWidth?: number |
||||
|
width?: number |
||||
|
height?: number |
||||
|
background?: string |
||||
|
direction?: string |
||||
|
tabIdx?: number |
||||
|
} |
||||
|
const props = withDefaults(defineProps<Props>(), { |
||||
|
list: () => [], |
||||
|
wrapperWidth: 200, |
||||
|
wrapperHeight: 192, |
||||
|
width: 200, |
||||
|
height: 192, |
||||
|
background: 'rgba(0, 0, 0, 0.03)', |
||||
|
direction: 'row', |
||||
|
tabIdx: 0 |
||||
|
}) |
||||
|
|
||||
|
// gradientColor: { |
||||
|
// type: Object, |
||||
|
// default: () => { |
||||
|
// return { |
||||
|
// startColor: '#A88AFD', |
||||
|
// endColor: '#CCB0FF' |
||||
|
// } |
||||
|
// } |
||||
|
// } |
||||
|
|
||||
|
// const padding = ref(0) |
||||
|
const copyTabIdx = ref(0) |
||||
|
const styles = computed(() => { |
||||
|
return { width: props.width + 'px', height: props.height + 'px' } |
||||
|
}) |
||||
|
|
||||
|
const emit = defineEmits(['click']) |
||||
|
onMounted(() => { |
||||
|
const timeId = setTimeout(() => { |
||||
|
clearTimeout(timeId) |
||||
|
nextTick(() => { |
||||
|
// scrollBox(props.tabIdx) |
||||
|
switchTab(0) |
||||
|
}) |
||||
|
}, 100) |
||||
|
}) |
||||
|
const ulRef = ref() |
||||
|
const scrollBoxRef = ref() |
||||
|
|
||||
|
function switchTab(index: number) { |
||||
|
copyTabIdx.value = index |
||||
|
emit('click', index) |
||||
|
} |
||||
|
|
||||
|
watch( |
||||
|
() => props.list, |
||||
|
() => { |
||||
|
nextTick(() => {}) |
||||
|
}, |
||||
|
{ |
||||
|
immediate: true |
||||
|
} |
||||
|
) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.switch-tabs { |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
padding: 0; |
||||
|
border-radius: 16px; |
||||
|
flex-wrap: nowrap; |
||||
|
.switch-tab-item { |
||||
|
position: relative; |
||||
|
z-index: 2; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
flex-shrink: 0; |
||||
|
margin-right: 0; |
||||
|
margin-bottom: 0; |
||||
|
border-radius: 8px; |
||||
|
transition: all 0.3s linear; |
||||
|
|
||||
|
.intro-icon { |
||||
|
width: 32px; |
||||
|
height: 32px; |
||||
|
margin-right: 16px; |
||||
|
} |
||||
|
.intro-wrapper { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
font-family: 'font_bold'; |
||||
|
.intro-name { |
||||
|
font-size: 16px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: #534f46; |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
.intro-name-en { |
||||
|
padding-top: 6px; |
||||
|
font-size: 10px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: #8e9090; |
||||
|
} |
||||
|
} |
||||
|
&.active { |
||||
|
background: #fff; |
||||
|
border-radius: 16px; |
||||
|
|
||||
|
// box-shadow: 0 -4px 0 0 rgb(177 189 220 / 10%) inset; |
||||
|
.intro-icon { |
||||
|
// filter: grayscale(1) brightness(300%); |
||||
|
} |
||||
|
.intro-wrapper { |
||||
|
.intro-name { |
||||
|
color: rgb(0 0 0 / 90%); |
||||
|
} |
||||
|
.intro-name-en { |
||||
|
color: rgb(0 0 0 / 90%); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.scroll-box { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
z-index: 1; |
||||
|
display: none; |
||||
|
border-radius: 0; |
||||
|
transition: all 0.3s linear; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,91 @@ |
|||||
|
<template> |
||||
|
<div class="btn-title-group"> |
||||
|
<div |
||||
|
v-for="(item, index) in list" |
||||
|
:key="index" |
||||
|
class="btn-item" |
||||
|
:class="{ active: currentTypeId === index, 'btn-en': language === 'en' }" |
||||
|
@click="changeType(item, index)" |
||||
|
> |
||||
|
<h4> |
||||
|
{{ switchLanguage(item, 'title') }} |
||||
|
</h4> |
||||
|
<div v-if="false && list.length > 1" class="saw"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue' |
||||
|
import { storeToRefs } from 'pinia' |
||||
|
import { useRootStore } from '@/store/root' |
||||
|
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
||||
|
|
||||
|
const { switchLanguage } = useSwitchLanguage() |
||||
|
const store = useRootStore() |
||||
|
const { language } = storeToRefs(store) |
||||
|
const currentTypeId = ref(0) |
||||
|
|
||||
|
const emit = defineEmits(['change-type']) |
||||
|
type TypeItem = { |
||||
|
title: string |
||||
|
titleEn: string |
||||
|
} |
||||
|
defineProps<{ |
||||
|
list: TypeItem[] |
||||
|
}>() |
||||
|
|
||||
|
function changeType(item: TypeItem, index: number) { |
||||
|
currentTypeId.value = index |
||||
|
emit('change-type', { ...item, order: currentTypeId.value }) |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.btn-title-group { |
||||
|
z-index: 1; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
width: fit-content; |
||||
|
.btn-item { |
||||
|
display: flex; |
||||
|
h4 { |
||||
|
height: 81px; |
||||
|
// width: 96px; |
||||
|
padding-bottom: 18px; |
||||
|
font-size: 32px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: rgb(0 0 0 / 40%); |
||||
|
line-height: 57px; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
&.btn-en { |
||||
|
h4 { |
||||
|
font-size: 19px; |
||||
|
} |
||||
|
} |
||||
|
&:nth-child(odd) { |
||||
|
.saw { |
||||
|
width: 0; |
||||
|
height: 26px; |
||||
|
margin-right: 40px; |
||||
|
margin-left: 40px; |
||||
|
background: #84754e; |
||||
|
} |
||||
|
} |
||||
|
&.active { |
||||
|
h4 { |
||||
|
font-size: 40px; |
||||
|
color: rgb(0 0 0 / 80%); |
||||
|
border-bottom: 6px solid #d7ba92; |
||||
|
} |
||||
|
&.btn-en { |
||||
|
h4 { |
||||
|
font-size: 21px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -1,9 +1,9 @@ |
|||||
declare interface Industry { |
declare interface Industry { |
||||
isSpecial: 0 | 1 //1特殊业态 反之不是
|
isSpecial: 0 | 1 //1特殊业态 反之不是
|
||||
industryId: number //唯一标识
|
|
||||
|
industryCode: string //唯一标识
|
||||
industryName: string //业态名称
|
industryName: string //业态名称
|
||||
industryNameEn: string //业态英文
|
industryNameEn: string //业态英文
|
||||
shopNum: number //店铺总数
|
shopNum: number //店铺总数
|
||||
industryList: Array<{ industryId: number; industryName: string; shopNum: number }> |
|
||||
|
industryList: Array<{ industryCode: string; industryName: string; shopNum: number }> |
||||
fileUrl?: string |
fileUrl?: string |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,22 @@ |
|||||
|
declare interface Region { |
||||
|
/** |
||||
|
* 区域编码 |
||||
|
*/ |
||||
|
regionCode: string |
||||
|
/** |
||||
|
* 区域名称 |
||||
|
*/ |
||||
|
regionName: string |
||||
|
/** |
||||
|
* 区域名称英文 |
||||
|
*/ |
||||
|
regionNameEn: string |
||||
|
/** |
||||
|
* 区域名称日文 |
||||
|
*/ |
||||
|
regionNameJa?: string |
||||
|
/** |
||||
|
* 区域名称其他语言 |
||||
|
*/ |
||||
|
regionNameOl?: string |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
<template> |
||||
|
<div class="brand-container"> |
||||
|
<!-- 店铺列表(业态和楼层控制) --> |
||||
|
<shopList></shopList> |
||||
|
<!-- 推荐店铺 --> |
||||
|
<recommendShop></recommendShop> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import recommendShop from './recommendShop.vue' |
||||
|
import shopList from './shopList.vue' |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
:deep(.swiper-wrapper) { |
||||
|
transition-timing-function: linear !important; /* 之前是ease-out */ |
||||
|
} |
||||
|
.brand-container { |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
padding-top: 152px; |
||||
|
padding-right: 0; |
||||
|
padding-left: 56px; |
||||
|
|
||||
|
--animate-duration: 0.6s; |
||||
|
--animate-delay: 1s; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,407 @@ |
|||||
|
<template> |
||||
|
<scrollView ref="shopScroll" class="format__scroll" :refresh-delay="200" :list="list"> |
||||
|
<div class="filter-wrapper"> |
||||
|
<div |
||||
|
v-for="(item, index) of copyList" |
||||
|
:key="item.industryCode" |
||||
|
:style="{ height: index === active ? 'fit-content' : '' }" |
||||
|
class="filter-div-f" |
||||
|
> |
||||
|
<div |
||||
|
ref="filterDivEl" |
||||
|
class="filter-div" |
||||
|
:class="{ 'filter-active': active == index && activeSon === -1 }" |
||||
|
:style="{ |
||||
|
background: activeSon === -1 ? getBackground(index) : '' |
||||
|
}" |
||||
|
@click.self="clickFormat(item, index, $event)" |
||||
|
> |
||||
|
<div class="left"> |
||||
|
<!-- :style="{ opacity: item.fileUrl ? 1 : 0 }" --> |
||||
|
<img :src="item.fileUrl ? item.fileUrl : normalIcon" class="format-img" alt="" /> |
||||
|
<p class="format-name">{{ switchLanguage(item, 'industryName') }}</p> |
||||
|
</div> |
||||
|
|
||||
|
<div class="right"> |
||||
|
<p class="format-number">{{ item.shopNum }}</p> |
||||
|
<img |
||||
|
v-if="item.industryList.length > 0" |
||||
|
class="saw-img" |
||||
|
src="@/assets/images/brand/down.svg" |
||||
|
:style="{ |
||||
|
transform: active === index ? 'rotate(180deg)' : '' |
||||
|
}" |
||||
|
alt="" |
||||
|
/> |
||||
|
<p v-if="false && item.shopNum" style="margin-right: 5px"> |
||||
|
<svg v-show="active != index" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path |
||||
|
d="M3.52851 5.52876C3.78886 5.26841 4.21097 5.26841 4.47132 5.52876L7.99992 9.05735L11.5285 5.52876C11.7889 5.26841 12.211 5.26841 12.4713 5.52876C12.7317 5.78911 12.7317 6.21122 12.4713 6.47157L8.47132 10.4716C8.21097 10.7319 7.78886 10.7319 7.52851 10.4716L3.52851 6.47157C3.26816 6.21122 3.26816 5.78911 3.52851 5.52876Z" |
||||
|
fill="black" |
||||
|
/> |
||||
|
</svg> |
||||
|
|
||||
|
<svg v-show="active == index" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path |
||||
|
d="M7.52851 5.52876C7.78886 5.26841 8.21097 5.26841 8.47132 5.52876L12.4713 9.52876C12.7317 9.78911 12.7317 10.2112 12.4713 10.4716C12.211 10.7319 11.7889 10.7319 11.5285 10.4716L7.99992 6.94297L4.47132 10.4716C4.21097 10.7319 3.78886 10.7319 3.52851 10.4716C3.26816 10.2112 3.26816 9.78911 3.52851 9.52876L7.52851 5.52876Z" |
||||
|
fill="white" |
||||
|
/> |
||||
|
</svg> |
||||
|
</p> |
||||
|
|
||||
|
<p v-else-if="false && !isFood" style="margin-right: 5px"> |
||||
|
<svg v-show="active != index" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path |
||||
|
d="M3.52851 5.52876C3.78886 5.26841 4.21097 5.26841 4.47132 5.52876L7.99992 9.05735L11.5285 5.52876C11.7889 5.26841 12.211 5.26841 12.4713 5.52876C12.7317 5.78911 12.7317 6.21122 12.4713 6.47157L8.47132 10.4716C8.21097 10.7319 7.78886 10.7319 7.52851 10.4716L3.52851 6.47157C3.26816 6.21122 3.26816 5.78911 3.52851 5.52876Z" |
||||
|
fill="black" |
||||
|
/> |
||||
|
</svg> |
||||
|
|
||||
|
<svg v-show="active == index" width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"> |
||||
|
<path |
||||
|
d="M7.52851 5.52876C7.78886 5.26841 8.21097 5.26841 8.47132 5.52876L12.4713 9.52876C12.7317 9.78911 12.7317 10.2112 12.4713 10.4716C12.211 10.7319 11.7889 10.7319 11.5285 10.4716L7.99992 6.94297L4.47132 10.4716C4.21097 10.7319 3.78886 10.7319 3.52851 10.4716C3.26816 10.2112 3.26816 9.78911 3.52851 9.52876L7.52851 5.52876Z" |
||||
|
fill="white" |
||||
|
/> |
||||
|
</svg> |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div |
||||
|
v-show="item.shopNum" |
||||
|
:ref="el => (formatListEl = el)" |
||||
|
class="format-list" |
||||
|
:class="{ 'format-list1': active != index }" |
||||
|
:style="{ height: copyList[index].industryList.length ? copyList[index].industryList.length * 56 + 'px' : 0 }" |
||||
|
> |
||||
|
<div |
||||
|
v-for="(items, cindex) of item.industryList" |
||||
|
:key="items.industryCode" |
||||
|
class="format-item" |
||||
|
:class="{ 'filter-active-child': activeSon == cindex }" |
||||
|
@click="clickItem(cindex, items, $event)" |
||||
|
> |
||||
|
<p class="format-name">{{ switchLanguage(items, 'industryName') }}</p> |
||||
|
<p class="format-number">{{ items.shopNum }}</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</scrollView> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import normalIcon from '@/assets/images/brand/format_normal.svg' |
||||
|
import { computed, ref, nextTick } from 'vue' |
||||
|
import scrollView from '@/base/ScrollView/ScrollView.vue' |
||||
|
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
||||
|
|
||||
|
const { switchLanguage } = useSwitchLanguage() |
||||
|
type Props = { |
||||
|
list: Industry[] |
||||
|
isFood?: boolean |
||||
|
} |
||||
|
|
||||
|
const shopScroll = ref() |
||||
|
const props = withDefaults(defineProps<Props>(), { |
||||
|
list: () => [], |
||||
|
isFood: false |
||||
|
}) |
||||
|
const emits = defineEmits(['clickFormat', 'clickFormatItem']) |
||||
|
|
||||
|
const active = ref(0) |
||||
|
const activeSon = ref(-1) |
||||
|
const imgRotate = ref(false) |
||||
|
const formatListEl = ref() |
||||
|
const copyList = computed(() => { |
||||
|
return [ |
||||
|
{ |
||||
|
fileUrl: require('@/assets/images/brand/all.svg'), |
||||
|
isSpecial: 0, |
||||
|
industryCode: 0, |
||||
|
industryName: '全部品牌', |
||||
|
industryNameEn: '', |
||||
|
shopNum: 0, |
||||
|
industryList: [] |
||||
|
}, |
||||
|
...props.list |
||||
|
] |
||||
|
}) |
||||
|
|
||||
|
const clickFormat = (item: Industry, index: number, $event: Event) => { |
||||
|
// nextTick(() => { |
||||
|
// const domfilter: HTMLDivElement = document.querySelectorAll('.filter-div')[index] as HTMLDivElement |
||||
|
|
||||
|
// if (item.industryList.length > 0) { |
||||
|
// domfilter.style.borderRadius = '8px 8px 0 0' |
||||
|
// } else { |
||||
|
// domfilter.style.borderRadius = '8px' |
||||
|
// } |
||||
|
// }) |
||||
|
if (item.industryList.length > 0) { |
||||
|
// console.log('formatListEl :>> ', $event) |
||||
|
const target: any = $event.target |
||||
|
//关闭、打开 |
||||
|
if (active.value === index) { |
||||
|
imgRotate.value = !imgRotate.value |
||||
|
target?.classList.add('filter-active') |
||||
|
// console.dir('$event.target :>> ', $event.target.nextElementSibling) |
||||
|
nextTick(() => { |
||||
|
// console.log('formatListEl :>> ', formatListEl) |
||||
|
// const domClass = formatListEl.value.classList |
||||
|
// const domClass = $event.target.nextElementSibling.children[index].classList |
||||
|
// console.log('domClass :>> ', domClass) |
||||
|
|
||||
|
if (index === active.value) { |
||||
|
// $event.target.classList.toggle('format-list1') |
||||
|
const dom: HTMLDivElement = document.querySelectorAll('.format-list')[index] as HTMLDivElement |
||||
|
const domfilter: HTMLDivElement = document.querySelectorAll('.filter-div')[index] as HTMLDivElement |
||||
|
// console.log('dom :>> ', dom) |
||||
|
dom.classList.toggle('format-list1') |
||||
|
|
||||
|
// if (dom.classList.contains('format-list1')) { |
||||
|
// domfilter.style.borderRadius = '8px' |
||||
|
// } else { |
||||
|
// domfilter.style.borderRadius = '8px 8px 0px 0px' |
||||
|
// } |
||||
|
|
||||
|
// if ($event.target.classList.includes('format-list1')) { |
||||
|
// $event.target.classList.remove('format-list1') |
||||
|
// } else { |
||||
|
// $event.target.classList.add('format-list1') |
||||
|
// } |
||||
|
} |
||||
|
// if (typeof domClass[1] === 'undefined') { |
||||
|
// formatListEl.value.add('format-list1') |
||||
|
// } else { |
||||
|
// formatListEl.value.remove('format-list1') |
||||
|
// } |
||||
|
}) |
||||
|
} |
||||
|
setTimeout(() => { |
||||
|
shopScroll.value.refresh() |
||||
|
}, 500) |
||||
|
} |
||||
|
emits('clickFormat', item, index) |
||||
|
active.value = index |
||||
|
activeSon.value = -1 |
||||
|
} |
||||
|
//点击format |
||||
|
function clickItem( |
||||
|
index: number, |
||||
|
item: { |
||||
|
industryCode: string |
||||
|
industryName: string |
||||
|
shopNum: number |
||||
|
}, |
||||
|
$event: Event |
||||
|
) { |
||||
|
activeSon.value = index |
||||
|
console.dir('$event :>> ', $event) |
||||
|
const dom: any = $event.target |
||||
|
for (let i = 0; i < dom?.length; i++) { |
||||
|
dom[i]?.classList.remove('filter-active') |
||||
|
} |
||||
|
setTimeout(() => { |
||||
|
shopScroll.value.refresh() |
||||
|
}, 20) |
||||
|
emits('clickFormatItem', item) |
||||
|
} |
||||
|
|
||||
|
const backgroundList = [ |
||||
|
'linear-gradient(180deg, #3C74E6 0%, #7ACAF8 100%)', |
||||
|
'linear-gradient(180deg, #ED7D2B 0%, #F1C369 100%)', |
||||
|
'linear-gradient(180deg, #7959D2 0%, #93A3DC 100%)', |
||||
|
'linear-gradient(180deg, #3EA154 0%, #3AD79E 100%)', |
||||
|
'linear-gradient(180deg, #DB5C8A 0%, #F39292 100%)' |
||||
|
] |
||||
|
function getBackground(index: number) { |
||||
|
if (active.value === index) { |
||||
|
return '#e00068' |
||||
|
} |
||||
|
} |
||||
|
// const scrollTo = () => { |
||||
|
// shopScroll.value.scrollTo(0, 0) |
||||
|
// } |
||||
|
// const refresh = () => { |
||||
|
// shopScroll.value.refresh() |
||||
|
// } |
||||
|
// const initData = () => { |
||||
|
// active.value = 0 |
||||
|
// initItem() |
||||
|
// } |
||||
|
// const initItem = () => { |
||||
|
// activeSon.value = -1 |
||||
|
// } |
||||
|
|
||||
|
// onBeforeMount(() => {}) |
||||
|
// onMounted(() => {}) |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.format__scroll { |
||||
|
overflow: hidden; |
||||
|
width: inherit; |
||||
|
height: inherit; |
||||
|
background-color: rgb(255 255 255 / 60%); |
||||
|
border-radius: 16px; |
||||
|
.filter-wrapper { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
// justify-content: flex-end; |
||||
|
// flex-wrap: wrap; |
||||
|
width: inherit; |
||||
|
height: fit-content; |
||||
|
} |
||||
|
.filter-div-f { |
||||
|
width: inherit; |
||||
|
height: 56px; |
||||
|
margin-bottom: 0; |
||||
|
&:nth-last-child(1) { |
||||
|
overflow: hidden; |
||||
|
border-radius: 0 0 16px 16px; |
||||
|
} |
||||
|
&:nth-child(1) { |
||||
|
overflow: hidden; |
||||
|
border-radius: 16px 16px 0 0; |
||||
|
} |
||||
|
.filter-div { |
||||
|
position: relative; |
||||
|
z-index: 2; |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
padding: 24px; |
||||
|
background: rgb(255 255 255 / 60%); |
||||
|
border: 0 solid rgb(255 255 255 / 60%); |
||||
|
border-radius: 16px; |
||||
|
flex-wrap: nowrap; |
||||
|
line-height: 22px; |
||||
|
|
||||
|
.left, |
||||
|
.right { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
.left { |
||||
|
margin-left: 0; |
||||
|
} |
||||
|
|
||||
|
.right { |
||||
|
position: relative; |
||||
|
// width: 52px; |
||||
|
padding-right: 0; |
||||
|
margin-left: -0; |
||||
|
} |
||||
|
|
||||
|
.format-img { |
||||
|
width: 16px; |
||||
|
height: 16px; |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
.format-name { |
||||
|
width: 111px; |
||||
|
height: 22px; |
||||
|
font-size: 14px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: #534f46; |
||||
|
font-weight: 700; |
||||
|
line-height: 22px; |
||||
|
|
||||
|
@include no-wrap(); |
||||
|
} |
||||
|
|
||||
|
.format-number { |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
margin-right: 8px; |
||||
|
font-size: 14px; |
||||
|
font-family: 'font_bold'; |
||||
|
text-align: right; |
||||
|
color: #615c29; |
||||
|
font-style: normal; |
||||
|
line-height: 22px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.filter-active { |
||||
|
height: 56px; |
||||
|
background: #e00068; |
||||
|
p { |
||||
|
color: #fff !important; |
||||
|
} |
||||
|
|
||||
|
.format-img { |
||||
|
filter: brightness(0) invert(100%); |
||||
|
} |
||||
|
.right { |
||||
|
.saw-img { |
||||
|
filter: brightness(0) invert(100%); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.filter-active-child { |
||||
|
background: #e000683d; |
||||
|
border-radius: 0 !important; |
||||
|
p { |
||||
|
color: #fff !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.format-list1 { |
||||
|
height: 0 !important; |
||||
|
} |
||||
|
|
||||
|
.format-list { |
||||
|
z-index: 1; |
||||
|
overflow: hidden; |
||||
|
background: rgb(255 255 255 / 20%); |
||||
|
border-radius: 0; |
||||
|
transition: all 0.3s ease; |
||||
|
|
||||
|
.format-item { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
height: 56px; |
||||
|
padding-right: 48px; |
||||
|
padding-left: 48px; |
||||
|
margin-bottom: 0; |
||||
|
border-radius: 0; |
||||
|
flex-wrap: nowrap; |
||||
|
|
||||
|
.format-name { |
||||
|
z-index: 500; |
||||
|
width: 113px; |
||||
|
margin-left: 0; |
||||
|
font-size: 14px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: rgb(0 0 0 / 60%); |
||||
|
line-height: 56px; |
||||
|
|
||||
|
@include no-wrap(); |
||||
|
} |
||||
|
|
||||
|
.format-number { |
||||
|
z-index: 500; |
||||
|
margin-right: 0; |
||||
|
font-size: 12px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: rgb(0 0 0 / 60%); |
||||
|
line-height: 14px; |
||||
|
} |
||||
|
&.filter-active { |
||||
|
background: #e000683d; |
||||
|
p { |
||||
|
color: #fff !important; |
||||
|
} |
||||
|
|
||||
|
border-radius: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,195 @@ |
|||||
|
<template> |
||||
|
<div v-if="recList.length" class="rec-container"> |
||||
|
<!-- 推荐标题 --> |
||||
|
<div class="rec-title"> |
||||
|
<li>{{ switchLanguage({ name: '热门推荐' }, 'name') }}</li> |
||||
|
<li>POPULAR BRANDS</li> |
||||
|
</div> |
||||
|
<!-- 显示当前选择的信息 --> |
||||
|
<div class="recommand-group animate__animated animate__fadeInRight"> |
||||
|
<!-- |
||||
|
:freeMode="{ |
||||
|
freeMode: false, |
||||
|
momentumRatio: 0.3, |
||||
|
momentumVelocityRatio: 0.3 |
||||
|
}" |
||||
|
:observer="true" |
||||
|
:observe-parents="true" |
||||
|
--> |
||||
|
<swiper |
||||
|
v-if="showList" |
||||
|
direction="vertical" |
||||
|
:autoplay=" |
||||
|
recList.length > 3 |
||||
|
? { |
||||
|
disableOnInteraction: false, |
||||
|
delay: 1000 |
||||
|
} |
||||
|
: false |
||||
|
" |
||||
|
:free-mode="{ |
||||
|
enabled: true |
||||
|
}" |
||||
|
:enabled="recList.length > 3" |
||||
|
:loop="recList.length > 3" |
||||
|
:speed="1000" |
||||
|
:modules="modules" |
||||
|
:looped-slides="3" |
||||
|
:loop-additional-slides="3" |
||||
|
:width="267" |
||||
|
:height="150" |
||||
|
:slides-per-view="1" |
||||
|
:space-between="24" |
||||
|
> |
||||
|
<swiper-slide v-for="(item, index) in recList" :key="index"> |
||||
|
<div :key="item.shopCode" class="item" :shopInfo="item" @click="handleShop(item)"> |
||||
|
<img v-if="item?.doorMaterialList?.at(0)" :src="item?.doorMaterialList?.at(0)" class="rec-img" alt="" /> |
||||
|
<img v-else :src="require('@/assets/images/brand/no-rec.svg')" class="rec-img no-rec" alt="" /> |
||||
|
<p class="bottom-title"> |
||||
|
<!-- <img class="rec-logo" :src="item.logoUrl ? item.logoUrl : require('@/assets/images/empty_small.svg')" alt="" /> --> |
||||
|
<span class="rec-name"> {{ switchLanguage(item, 'shopName') }}</span> |
||||
|
<!-- <span class="rec-floor"> <img :src="item.industryUrl" alt="" />{{ item.floor }} </span> --> |
||||
|
</p> |
||||
|
</div> |
||||
|
</swiper-slide> |
||||
|
</swiper> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue' |
||||
|
import { Autoplay, FreeMode } from 'swiper' |
||||
|
import { Swiper, SwiperSlide } from 'swiper/vue' |
||||
|
import 'swiper/css' |
||||
|
import 'swiper/css/free-mode' |
||||
|
import { getBrandInfo } from '@/http/api/brand/index' |
||||
|
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
||||
|
import { useRootStore } from '@/store/root' |
||||
|
const store = useRootStore() |
||||
|
|
||||
|
const { switchLanguage } = useSwitchLanguage() |
||||
|
const recList = ref<Shop[]>([]) |
||||
|
const modules = [Autoplay, FreeMode] |
||||
|
const showList = ref(false) |
||||
|
|
||||
|
function handleShop(item: Shop) { |
||||
|
store.SET_SHOP(item) |
||||
|
store.SET_SHOW_DETAIL(true) |
||||
|
} |
||||
|
getBrandInfo() |
||||
|
.then(({ data }) => { |
||||
|
recList.value = data.recommendList |
||||
|
}) |
||||
|
.finally(() => { |
||||
|
showList.value = true |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
:deep(.swiper-wrapper) { |
||||
|
transition-timing-function: linear !important; /* 之前是ease-out */ |
||||
|
} |
||||
|
.rec-container { |
||||
|
position: relative; |
||||
|
width: 268px; |
||||
|
height: 1080px; |
||||
|
padding-top: 172px; |
||||
|
padding-left: 48px; |
||||
|
margin-top: -152px; |
||||
|
margin-left: 28px; |
||||
|
background-image: linear-gradient(170deg, rgb(255 255 255 / 40%) 0%, rgb(255 255 255 / 8%) 80.56%, rgb(255 255 255 / 0%) 100%); |
||||
|
|
||||
|
--animate-duration: 0.6s; |
||||
|
--animate-delay: 1s; |
||||
|
.rec-title { |
||||
|
font-size: 24px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: #534f46; |
||||
|
li:nth-child(2) { |
||||
|
margin-top: 5px; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
} |
||||
|
.recommand-group { |
||||
|
overflow: hidden; |
||||
|
width: 192px; |
||||
|
height: 696px; |
||||
|
margin-top: 24px; |
||||
|
:deep(.swiper-slide) { |
||||
|
width: 172px; |
||||
|
height: 146px; |
||||
|
} |
||||
|
.item { |
||||
|
width: 172px; |
||||
|
height: 146px; |
||||
|
padding: 8px auto 16px; |
||||
|
background-color: #fff; |
||||
|
border-radius: 16px; |
||||
|
.rec-img { |
||||
|
position: absolute; |
||||
|
top: 8px; |
||||
|
left: 38px; |
||||
|
overflow: hidden; |
||||
|
width: 96px; |
||||
|
height: 96px; |
||||
|
border-radius: 0; |
||||
|
object-fit: cover; |
||||
|
&.no-rec { |
||||
|
object-fit: scale-down; |
||||
|
} |
||||
|
} |
||||
|
.bottom-title { |
||||
|
position: absolute; |
||||
|
bottom: 16px; |
||||
|
left: 0; |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
width: 100%; |
||||
|
height: 22px; |
||||
|
padding: 0; |
||||
|
background: rgb(0 0 0 / 0%); |
||||
|
border-radius: 0; |
||||
|
line-height: initial; |
||||
|
.rec-logo { |
||||
|
position: absolute; |
||||
|
top: -22px; |
||||
|
left: 12px; |
||||
|
width: 48px; |
||||
|
height: 48px; |
||||
|
padding: 0; |
||||
|
background: #fff; |
||||
|
border-radius: 4px; |
||||
|
object-fit: scale-down; |
||||
|
} |
||||
|
.rec-name { |
||||
|
width: 100%; |
||||
|
margin-top: 0; |
||||
|
margin-left: 0; |
||||
|
font-size: 14px; |
||||
|
font-family: 'font_bold'; |
||||
|
text-align: center; |
||||
|
color: #534f46; |
||||
|
|
||||
|
@include no-wrap(); |
||||
|
} |
||||
|
.rec-floor { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
height: 16px; |
||||
|
padding-right: 0; |
||||
|
margin-top: 5px; |
||||
|
margin-left: 0; |
||||
|
font-size: 14px; |
||||
|
color: rgb(255 255 255 / 80%); |
||||
|
img { |
||||
|
width: 16px; |
||||
|
height: 16px; |
||||
|
// filter: grayscale(100%) opacity(40%); |
||||
|
margin-right: 8px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,533 @@ |
|||||
|
<template> |
||||
|
<div class="shop-list"> |
||||
|
<!-- --> |
||||
|
<switchtab |
||||
|
class="switch-btn" |
||||
|
:width="364" |
||||
|
:height="68" |
||||
|
:wrapper-width="1092" |
||||
|
:wrapper-height="68" |
||||
|
direction="row" |
||||
|
:list="list" |
||||
|
@click="handleSwitch" |
||||
|
/> |
||||
|
<!-- 店铺 --> |
||||
|
<!-- <scroll-view |
||||
|
class="shop-scroll" |
||||
|
:style="{ |
||||
|
top: recList.length === 0 ? '360px' : '' |
||||
|
}" |
||||
|
:list="selectedShopList" |
||||
|
ref="shopScroll" |
||||
|
> --> |
||||
|
|
||||
|
<swiper |
||||
|
ref="myScroll" |
||||
|
class="shop-scroll animate__animated animate__fadeInUp" |
||||
|
:speed="300" |
||||
|
:direction="'vertical'" |
||||
|
:slides-per-view="'auto'" |
||||
|
:free-mode="{ |
||||
|
enabled: true, |
||||
|
momentumRatio: 0.3, |
||||
|
momentumVelocityRatio: 0.3 |
||||
|
}" |
||||
|
:observer="true" |
||||
|
:observe-parents="true" |
||||
|
:scrollbar="{ el: '.swiper-scrollbar' }" |
||||
|
:modules="modulesShop" |
||||
|
@after-init="getSwiper" |
||||
|
@reach-end="myScrollEnd" |
||||
|
> |
||||
|
<!-- |
||||
|
@observer-update="updateSwiper" --> |
||||
|
<swiper-slide v-for="(items, index) in pageList" :key="index" :data-floor-name="items.name"> |
||||
|
<ul class="shop-items"> |
||||
|
<div v-show="items.shopList && items.shopList.length" ref="shopDiv" class="shop-div" :data-floorname="items.name"> |
||||
|
<div class="shop-floor"> |
||||
|
{{ items.name }} |
||||
|
<div class="top-right-txt" :style="{ width: items.name !== device.floor ? '0px' : '' }"> |
||||
|
<img v-if="items.name === device.floor" src="../../assets/images/brand/pos.svg" class="pos-icon" alt="" /> |
||||
|
<span v-if="items.name === device.floor">{{ $t('brand.pos') }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- :style="{ 'grid-template-columns': isH && recList.length === 0 ? 'repeat(5, 240px)' : null }" --> |
||||
|
<div class="shop-wrapper"> |
||||
|
<shopItem v-for="(item, idx) of items.shopList" :key="idx" class="item" :shop="item" @click="handleShop(item)" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</ul> |
||||
|
</swiper-slide> |
||||
|
<div class="swiper-scrollbar"></div> |
||||
|
</swiper> |
||||
|
|
||||
|
<!-- </scroll-view> --> |
||||
|
|
||||
|
<!-- 楼层和业态 --> |
||||
|
<div class="right-control-area animate__animated animate__fadeInRight"> |
||||
|
<transition |
||||
|
enter-active-class="animate__animated animate__fadeInRight" |
||||
|
leave-active-class="animate__animated animate__fadeOutRight" |
||||
|
mode="out-in" |
||||
|
> |
||||
|
<!-- 区域 --> |
||||
|
<div v-if="toggleFormatAndFloors === 0" class="floor-container"> |
||||
|
<ul class="floors-items"> |
||||
|
<li |
||||
|
v-for="(item, index) of regionList" |
||||
|
:key="item.regionCode" |
||||
|
class="floor-item" |
||||
|
:class="{ active: areaIdx === index }" |
||||
|
@click="handleArea(item, index)" |
||||
|
> |
||||
|
{{ switchLanguage(item, 'regionName') }} |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<!-- 业态 --> |
||||
|
<div v-else-if="toggleFormatAndFloors === 2" key="format" class="format-items"> |
||||
|
<filterFormatAndFloor |
||||
|
ref="collapseRef" |
||||
|
:list="shopFormatList" |
||||
|
@click-format-item="handleFormatChild" |
||||
|
@click-format="handleFormat" |
||||
|
/> |
||||
|
</div> |
||||
|
<!-- 楼层 scroll-view --> |
||||
|
<div v-else-if="toggleFormatAndFloors === 1" key="floors" class="floor-container" :refreshDelay="200"> |
||||
|
<ul class="floors-items"> |
||||
|
<li |
||||
|
v-for="(item, index) of floorsList" |
||||
|
:key="item.floorCode" |
||||
|
class="floor-item" |
||||
|
:class="{ active: floorIdx === index }" |
||||
|
@click="handleFloor(item, index)" |
||||
|
> |
||||
|
{{ item.floor }} |
||||
|
<img v-if="device.floor === item.floor" class="current-pos" src="@/assets/images/brand/currentPos.svg" alt="" /> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</transition> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, computed, nextTick, shallowRef, onMounted } from 'vue' |
||||
|
import { FreeMode } from 'swiper' |
||||
|
import { Swiper, SwiperSlide } from 'swiper/vue' |
||||
|
import 'swiper/css' |
||||
|
import 'swiper/css/pagination' |
||||
|
import 'swiper/css/free-mode' |
||||
|
// import ScrollView from '@/base/ScrollView/ScrollView.vue' |
||||
|
// import CollapseVue from '@/base/Collapse/Collapse.vue' |
||||
|
|
||||
|
import { getBrandInfo } from '@/http/api/brand/index' |
||||
|
import { getRegionList } from '@/http/api/base/index' |
||||
|
|
||||
|
import switchtab from '@/components/SwitchTab/SwitchTab.vue' |
||||
|
import filterFormatAndFloor from '@/views/Brand/filterFormatAndFloor.vue' |
||||
|
import shopItem from '@/components/ShopItem/ShopItem.vue' |
||||
|
|
||||
|
import { useStatistics } from '@/composables/useStatistics' |
||||
|
|
||||
|
import { usePage } from '@/composables/usePage' |
||||
|
import { storeToRefs } from 'pinia' |
||||
|
import { useRootStore } from '@/store/root' |
||||
|
import { GroupList } from '@/http/api/brand/types' |
||||
|
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
||||
|
|
||||
|
const store = useRootStore() |
||||
|
const { device, currentBuildingFloorsList, shopListGroupByFloor, shopListGroupByIndustry } = storeToRefs(store) |
||||
|
|
||||
|
const { switchLanguage } = useSwitchLanguage() |
||||
|
// const shopScroll = computed(() => document.querySelector('.shop-scroll>.swiper-wrapper')) |
||||
|
const swiperRef = shallowRef() |
||||
|
|
||||
|
const modulesShop = [FreeMode] |
||||
|
|
||||
|
const toggleFormatAndFloors = ref<0 | 1 | 2>(0) |
||||
|
|
||||
|
const list = [ |
||||
|
{ |
||||
|
name: '区域筛选', |
||||
|
en: 'AREA', |
||||
|
icon: require('../../assets/images/brand/icon_area.svg'), |
||||
|
iconSel: require('../../assets/images/brand/icon_area_sel.svg') |
||||
|
}, |
||||
|
{ |
||||
|
name: '楼层筛选', |
||||
|
en: 'FLOOR', |
||||
|
icon: require('../../assets/images/brand/icon_floor.svg'), |
||||
|
iconSel: require('../../assets/images/brand/icon_floor_sel.svg') |
||||
|
}, |
||||
|
{ |
||||
|
name: '业态筛选', |
||||
|
en: 'FORMAT', |
||||
|
icon: require('../../assets/images/brand/icon_format.svg'), |
||||
|
iconSel: require('../../assets/images/brand/icon_format_sel.svg') |
||||
|
} |
||||
|
] |
||||
|
|
||||
|
const regionList = ref<Region[]>([]) //区域列表 |
||||
|
const shopFormatList = ref<Industry[]>([]) //业态列表 |
||||
|
// const brandFloorsList = ref([]) //楼层列表 |
||||
|
const selectedShopList = shallowRef<GroupList>([]) //店铺列表 |
||||
|
const selfListByFloor = ref<GroupList>([]) |
||||
|
const selfListByIndustry = ref<GroupList>([]) |
||||
|
|
||||
|
const floorIdx = ref(0) //楼层索引 |
||||
|
const formatIdx = ref(0) //业态索引 |
||||
|
const areaIdx = ref(0) //区域索引 |
||||
|
const myScroll = ref() |
||||
|
// type PageList = { name: string; shopList: Shop[] } |
||||
|
const { scrollEnd, pageList } = usePage(selectedShopList, myScroll) |
||||
|
|
||||
|
//楼层列表 |
||||
|
const floorsList = computed(() => { |
||||
|
return [ |
||||
|
{ |
||||
|
floor: 'ALL', |
||||
|
floorCode: 0, |
||||
|
floorMapUrl: '', |
||||
|
floorOrder: -1, |
||||
|
floorMapCode: '' |
||||
|
}, |
||||
|
...currentBuildingFloorsList.value |
||||
|
] |
||||
|
}) |
||||
|
const recList = ref<Shop[]>([]) |
||||
|
|
||||
|
getBrandInfo().then(({ data }) => { |
||||
|
shopFormatList.value = [ |
||||
|
// { |
||||
|
// fileUrl: require('@/assets/images/brand/all.svg'), |
||||
|
// isSpecial: 0, |
||||
|
// industryCode: 0, |
||||
|
// industryName: '全部品牌', |
||||
|
// industryNameEn: '', |
||||
|
// shopNum: 0, |
||||
|
// industryList: [] |
||||
|
// }, |
||||
|
...data.industryFatherList |
||||
|
] |
||||
|
recList.value = data.recommendList |
||||
|
}) |
||||
|
getRegionList().then(({ data }) => { |
||||
|
if (data) { |
||||
|
regionList.value = [ |
||||
|
{ |
||||
|
regionCode: '-1', |
||||
|
regionName: '全部区域', |
||||
|
regionNameEn: 'ALL' |
||||
|
}, |
||||
|
...data |
||||
|
] |
||||
|
} |
||||
|
}) |
||||
|
selfListByFloor.value = [...shopListGroupByFloor.value] |
||||
|
selfListByIndustry.value = [...shopListGroupByIndustry.value] |
||||
|
|
||||
|
onMounted(() => { |
||||
|
selectedShopList.value = selfListByIndustry.value |
||||
|
}) |
||||
|
function getSwiper(obj: any) { |
||||
|
swiperRef.value = obj |
||||
|
swiperRef.value.update() |
||||
|
} |
||||
|
|
||||
|
function updateSwiper(time = 300, isToCurentFloor = false) { |
||||
|
nextTick(() => { |
||||
|
const timeId = setTimeout(() => { |
||||
|
clearTimeout(timeId) |
||||
|
// showList.value = true |
||||
|
if (swiperRef.value) { |
||||
|
// console.dir('swiperRef.value :>> ', swiperRef) |
||||
|
swiperRef.value.update() |
||||
|
if (isToCurentFloor && swiperRef.value) { |
||||
|
for (let t = 0; t < swiperRef.value.slides.length; t++) { |
||||
|
const element = swiperRef.value.slides[t] |
||||
|
if (element.dataset.floorName === device.value.floor) { |
||||
|
swiperRef.value.slideTo(t, 10) |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
swiperRef.value.slideTo(0, 30) |
||||
|
} |
||||
|
// shopScroll.value.style.transform = 'translate3d(0px, 0px, 0px)' |
||||
|
|
||||
|
// swiperRef.slideTo(0) |
||||
|
// swiperRef.value.children[0].style.transform = 'translate3d(0px, 0px, 0px)' |
||||
|
} |
||||
|
}, time) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//切换控制 |
||||
|
function handleSwitch(index: number) { |
||||
|
formatIdx.value = 0 |
||||
|
floorIdx.value = 0 |
||||
|
areaIdx.value = 0 |
||||
|
// console.log('swiperRef.value.swiper :>> ', swiperRef) |
||||
|
if (index === 0) { |
||||
|
toggleFormatAndFloors.value = 0 |
||||
|
selectedShopList.value = selfListByIndustry.value |
||||
|
updateSwiper() |
||||
|
} else if (index === 1) { |
||||
|
toggleFormatAndFloors.value = 1 |
||||
|
selectedShopList.value = selfListByIndustry.value |
||||
|
updateSwiper() |
||||
|
} else { |
||||
|
toggleFormatAndFloors.value = 2 |
||||
|
selectedShopList.value = selfListByFloor.value |
||||
|
updateSwiper() |
||||
|
} |
||||
|
} |
||||
|
//点击楼层 |
||||
|
function handleFloor(item: Floor, index: number) { |
||||
|
if (index === floorIdx.value) { |
||||
|
return |
||||
|
} |
||||
|
floorIdx.value = index |
||||
|
if (index === 0) { |
||||
|
selectedShopList.value = selfListByIndustry.value |
||||
|
updateSwiper() |
||||
|
|
||||
|
return |
||||
|
} |
||||
|
selectedShopList.value = selfListByIndustry.value.map(format => ({ |
||||
|
...format, |
||||
|
shopList: format.shopList.filter(shop => shop.floor === item.floor) |
||||
|
})) |
||||
|
updateSwiper() |
||||
|
} |
||||
|
//点击区域 |
||||
|
function handleArea(item: Region, index: number) { |
||||
|
if (index === areaIdx.value) { |
||||
|
return |
||||
|
} |
||||
|
areaIdx.value = index |
||||
|
if (index === 0) { |
||||
|
selectedShopList.value = selfListByIndustry.value |
||||
|
updateSwiper() |
||||
|
|
||||
|
return |
||||
|
} |
||||
|
selectedShopList.value = selfListByIndustry.value.map(format => ({ |
||||
|
...format, |
||||
|
shopList: format.shopList.filter(shop => shop.regionCode === item.regionCode) |
||||
|
})) |
||||
|
updateSwiper() |
||||
|
} |
||||
|
//业态 |
||||
|
function handleFormat(item: Industry, index: number) { |
||||
|
if (index === formatIdx.value) { |
||||
|
return |
||||
|
} |
||||
|
useStatistics({ tag: 'industry', industryCode: item.industryCode }) |
||||
|
|
||||
|
formatIdx.value = index |
||||
|
if (item.industryName === '全部品牌') { |
||||
|
selectedShopList.value = selfListByFloor.value |
||||
|
updateSwiper() |
||||
|
|
||||
|
return |
||||
|
} |
||||
|
selectedShopList.value = selfListByFloor.value.map(floor => ({ |
||||
|
...floor, |
||||
|
shopList: floor.shopList.filter(shop => shop.industryFatherName === item.industryName) |
||||
|
})) |
||||
|
updateSwiper() |
||||
|
} |
||||
|
function handleFormatChild(item: any) { |
||||
|
selectedShopList.value = selfListByFloor.value.map(floor => ({ |
||||
|
...floor, |
||||
|
shopList: floor.shopList.filter(shop => shop.industryCode === item.industryCode) |
||||
|
})) |
||||
|
updateSwiper() |
||||
|
} |
||||
|
//点击店铺 |
||||
|
function handleShop(item: Shop) { |
||||
|
store.SET_SHOP(item) |
||||
|
store.SET_SHOW_DETAIL(true) |
||||
|
} |
||||
|
function myScrollEnd() { |
||||
|
scrollEnd() |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
:deep(.switch-tabs) { |
||||
|
padding: 0; |
||||
|
} |
||||
|
.switch-btn { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
} |
||||
|
.shop-list { |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
overflow: hidden; |
||||
|
width: 1598px; |
||||
|
height: 1080px; |
||||
|
padding-top: 0; |
||||
|
padding-left: 0; |
||||
|
.right-control-area { |
||||
|
position: relative; |
||||
|
width: 230px; |
||||
|
height: 622px; |
||||
|
margin-top: 144px; |
||||
|
margin-left: 28px; |
||||
|
|
||||
|
.format-items { |
||||
|
position: relative; |
||||
|
width: 230px; |
||||
|
height: 645px; |
||||
|
margin-top: 0; |
||||
|
margin-right: 0; |
||||
|
transition: all 0.3s linear; |
||||
|
} |
||||
|
.floor-container { |
||||
|
overflow: hidden; |
||||
|
width: 230px; |
||||
|
margin-top: 0; |
||||
|
margin-right: 0; |
||||
|
border-radius: 0; |
||||
|
// position: absolute; |
||||
|
// right: 0; |
||||
|
// top: 80px; |
||||
|
.floors-items { |
||||
|
// display: grid; |
||||
|
// grid-template-columns: repeat(6, 108px); |
||||
|
// column-gap: 8px; |
||||
|
// row-gap: 8px; |
||||
|
// place-items: start end; |
||||
|
// justify-items: end; |
||||
|
|
||||
|
// justify-content: flex-end; |
||||
|
display: flex; |
||||
|
overflow: hidden; |
||||
|
padding-bottom: 0; |
||||
|
margin-top: 0; |
||||
|
border-radius: 0; |
||||
|
// flex-direction: row; |
||||
|
// flex-wrap: wrap; |
||||
|
flex-flow: row wrap; |
||||
|
gap: 8px 6px; |
||||
|
// justify-content: flex-end; |
||||
|
// flex-wrap: wrap; |
||||
|
|
||||
|
animation-duration: 0.3s; |
||||
|
border-bottom: 0 solid rgb(0 0 0 / 0%); |
||||
|
.floor-item { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
width: 230px; |
||||
|
height: 72px; |
||||
|
font-size: 14px; |
||||
|
font-family: 'font_bold'; |
||||
|
text-align: center; |
||||
|
color: #534f46; |
||||
|
background: rgb(255 255 255 / 50%); |
||||
|
border: 2px solid #fff; |
||||
|
border-radius: 16px; |
||||
|
line-height: 72px; |
||||
|
backdrop-filter: blur(11px); |
||||
|
.current-pos { |
||||
|
position: absolute; |
||||
|
top: 28px; |
||||
|
right: 64px; |
||||
|
width: 16px; |
||||
|
} |
||||
|
&:first-of-type { |
||||
|
width: 230px; |
||||
|
// margin-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
// &:last-of-type { |
||||
|
// border-bottom-left-radius: 8px; |
||||
|
// border-bottom-right-radius: 8px; |
||||
|
// } |
||||
|
&.active { |
||||
|
&::after { |
||||
|
position: absolute; |
||||
|
top: 52px; |
||||
|
left: 0; |
||||
|
width: 224px; |
||||
|
height: 0; |
||||
|
content: ''; |
||||
|
// border-bottom: 4px rgba(255, 255, 255, 0) solid; |
||||
|
// border-image: linear-gradient(to right, #ea4b75, #ee8ea0) 1 10 round; |
||||
|
} |
||||
|
.current-pos { |
||||
|
filter: brightness(0) invert(100%); |
||||
|
} |
||||
|
|
||||
|
color: #fff; |
||||
|
background: #e00068; |
||||
|
// &:first-of-type { |
||||
|
// // border-top-left-radius: 8px; |
||||
|
// // border-top-right-radius: 8px; |
||||
|
// } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.shop-scroll { |
||||
|
width: 1308px; |
||||
|
height: 770px; |
||||
|
padding-bottom: 30px; |
||||
|
margin-top: 100px; |
||||
|
margin-left: 0; |
||||
|
.swiper-slide, |
||||
|
.swiper-wrapper { |
||||
|
height: auto; |
||||
|
} |
||||
|
.shop-items { |
||||
|
.shop-div { |
||||
|
margin-bottom: 40px; |
||||
|
.shop-floor { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
// vertical-align: text-bottom; |
||||
|
// justify-content: space-between; |
||||
|
padding-right: 0; |
||||
|
margin-bottom: 8px; |
||||
|
margin-left: 0; |
||||
|
font-size: 28px; |
||||
|
font-family: 'font_bold'; |
||||
|
color: #534f46; |
||||
|
font-style: normal; |
||||
|
font-weight: 700; |
||||
|
.top-right-txt { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
width: fit-content; |
||||
|
height: 14px; |
||||
|
padding: 0; |
||||
|
margin-right: 0; |
||||
|
margin-bottom: 3px; |
||||
|
font-size: 12px; |
||||
|
color: #615c59; |
||||
|
background: rgb(255 255 255 / 0%); |
||||
|
border-radius: 0; |
||||
|
|
||||
|
@include no-wrap(); |
||||
|
.pos-icon { |
||||
|
height: 14px; |
||||
|
margin-right: 6px; |
||||
|
margin-left: 24px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.shop-wrapper { |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(6, 212px); |
||||
|
gap: 16px 8px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||