|
After Width: | Height: | Size: 448 B |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 322 B |
|
After Width: | Height: | Size: 3.4 MiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 280 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 380 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 809 B |
|
After Width: | Height: | Size: 715 B |
|
After Width: | Height: | Size: 500 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(0 0 0 / 40%); |
|||
animation-duration: 0.3s; |
|||
backdrop-filter: blur(10px); |
|||
.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,332 @@ |
|||
<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="carousel"> |
|||
<swiper |
|||
:autoplay="{ |
|||
delay: 5000 |
|||
}" |
|||
:observer="true" |
|||
:observe-parents="true" |
|||
:modules="modules" |
|||
:effect="'fade'" |
|||
:pagination="{ el: '.detail' }" |
|||
> |
|||
<swiper-slide v-for="(item, index) in shop.doorMaterialList" :key="index" class="slide"> |
|||
<img :src="item.search(config.sourceUrl) >= 0 ? item : config.sourceUrl + item" class="banner" /> |
|||
</swiper-slide> |
|||
</swiper> |
|||
<img v-if="!shop.doorMaterialList?.length" src="../../assets/images/nodata.svg" class="banner no-data" alt="" /> |
|||
<div class="swiper-pagination detail"></div> |
|||
</div> |
|||
<!-- logo --> |
|||
<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/header/logo.svg" alt="" /> |
|||
</div> |
|||
|
|||
<!-- 名称和属性 --> |
|||
<div class="name-wrapper"> |
|||
<div class="marquee-wrapper"> |
|||
<marquees :speed="40" :delay="0.8" class="name" :content="switchLanguage(shop, 'shopName')" |
|||
>{{ switchLanguage(shop, 'shopName') }} |
|||
</marquees> |
|||
</div> |
|||
<!-- 点赞 --> |
|||
<div class="like-container" :class="{ 'no-click': isLiked }" @click="clickLike"> |
|||
<img |
|||
:src="isLiked ? require('@/assets/images/shopDetail/like_sel.svg') : require('@/assets/images/shopDetail/like_normal.svg')" |
|||
alt="" |
|||
/> |
|||
<span>{{ $t('shop.like') }}</span> |
|||
</div> |
|||
|
|||
<!-- 属性 --> |
|||
<div class="shop-attr-group"> |
|||
<div class="ul"> |
|||
<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 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> |
|||
<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> |
|||
</div> |
|||
|
|||
<!-- 详情 --> |
|||
<scroll-view :list="[switchLanguage(shop, 'intro')]" class="intro-scroll" :scrollbar="true" :pull-up="false" :refresh-delay="500"> |
|||
<p class="intro" v-text="switchLanguage(shop, 'intro')"></p> |
|||
</scroll-view> |
|||
<!-- 导航按钮 --> |
|||
<div v-if="shop.yaxis" class="go" @click="handleGo"> |
|||
<img src="@/assets/images/shopDetail/bg_go.png" alt="" /> |
|||
<h5>{{ $t('shop.goBtn') }}</h5> |
|||
</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 { ref } from 'vue' |
|||
import { useRouter } from 'vue-router' |
|||
import { useStatistics } from '@/composables/useStatistics' |
|||
import { getBrandStar, setBrandStar } from '@/http/api/brand/index' |
|||
|
|||
import { storeToRefs } from 'pinia' |
|||
import { useRootStore } from '@/store/root' |
|||
const store = useRootStore() |
|||
const { shop, config, device } = storeToRefs(store) |
|||
const router = useRouter() |
|||
|
|||
const modules = [Autoplay, Pagination, EffectFade] |
|||
const isLiked = ref(false) //是否点击like |
|||
//关闭窗口 |
|||
function close() { |
|||
store.SET_SHOW_DETAIL(false) |
|||
} |
|||
//导航 |
|||
function handleGo() { |
|||
store.SET_SHOW_DETAIL(false) |
|||
store.SET_SHOW_SEARCH(false) |
|||
router.push('/nav') |
|||
} |
|||
/** |
|||
* 点击like |
|||
*/ |
|||
function clickLike() { |
|||
try { |
|||
setBrandStar({ projectCode: device.value.projectCode, shopCode: shop.value.shopCode as string }).then(res => { |
|||
if (res.code === 200) { |
|||
isLiked.value = true |
|||
} |
|||
}) |
|||
} catch (error) { |
|||
console.log('error :>> ', error) |
|||
} |
|||
} |
|||
useStatistics({ tag: 'shop', shopCode: shop.value.shopCode }) |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
:deep(.bscroll-vertical-scrollbar) { |
|||
background: rgb(0 0 0 / 1%); |
|||
border-radius: 4px; |
|||
opacity: 1 !important; |
|||
.bscroll-indicator { |
|||
background: #b7a475 !important; |
|||
border: none !important; |
|||
border-radius: 4px !important; |
|||
box-shadow: 0 8px 20px rgb(0 0 0 / 10%); |
|||
} |
|||
} |
|||
.shop-detail-wrapper { |
|||
--swiper-pagination-bullet-horizontal-gap: 8px; |
|||
--swiper-pagination-bullet-width: 24px; |
|||
--swiper-pagination-bullet-height: 4px; |
|||
--swiper-pagination-bullet-inactive-color: rgb(255 255 255 / 60%) !important; |
|||
--swiper-theme-color: #5a6670; |
|||
--animate-duration: 0.3s; |
|||
|
|||
position: relative; |
|||
z-index: 9003; |
|||
display: inline-block; |
|||
width: 1586px; |
|||
height: 492px; |
|||
margin-top: 325px; |
|||
margin-left: 175px; |
|||
background: linear-gradient(to bottom, #d9d3c4 0%, #d9d3c4 52%, #e6e3db 52%, #e6e3db 100%); |
|||
|
|||
.carousel { |
|||
position: relative; |
|||
z-index: 0; |
|||
overflow: hidden; |
|||
width: 852px; |
|||
height: 480px; |
|||
margin-top: -32px; |
|||
margin-left: -50px; |
|||
background: rgb(255 255 255 / 71.9%); |
|||
border-radius: 0; |
|||
.banner { |
|||
width: 100%; |
|||
height: 480px; |
|||
border-radius: 0; |
|||
object-fit: cover; |
|||
} |
|||
.no-data { |
|||
padding: 30px 192px; |
|||
background: #fff; |
|||
} |
|||
.detail { |
|||
bottom: 70px; |
|||
left: 78%; |
|||
width: 120px; |
|||
} |
|||
} |
|||
.logo-wrapper { |
|||
position: absolute; |
|||
top: -32px; |
|||
left: 300px; |
|||
z-index: 1; |
|||
width: 152px; |
|||
height: 152px; |
|||
padding: 12px; |
|||
background: #fff; |
|||
border-radius: 0; |
|||
img { |
|||
width: 128px; |
|||
height: 128px; |
|||
object-fit: scale-down; |
|||
} |
|||
} |
|||
.name-wrapper { |
|||
position: absolute; |
|||
top: 40px; |
|||
left: 852px; |
|||
z-index: 1; |
|||
.marquee-wrapper { |
|||
overflow: hidden; |
|||
width: 700px; |
|||
margin-bottom: 12px; |
|||
white-space: nowrap; |
|||
|
|||
.name { |
|||
display: inline-block; |
|||
height: 36px; |
|||
font-size: 28px; |
|||
font-family: 'font_bold'; |
|||
color: #595447; |
|||
font-weight: 700; |
|||
} |
|||
} |
|||
.like-container { |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 46px; |
|||
img { |
|||
width: 24px; |
|||
margin-right: 8px; |
|||
} |
|||
span { |
|||
font-size: 16px; |
|||
font-family: 'font_regular'; |
|||
color: #84754e; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 24px; |
|||
} |
|||
|
|||
&.isLiked { |
|||
pointer-events: none; |
|||
} |
|||
} |
|||
|
|||
.shop-attr-group { |
|||
width: 500px; |
|||
.ul { |
|||
display: flex; |
|||
margin-bottom: 17px; |
|||
} |
|||
.working-item { |
|||
display: flex; |
|||
align-items: center; |
|||
img { |
|||
width: 20px; |
|||
height: 20px; |
|||
margin-right: 8px; |
|||
} |
|||
span { |
|||
margin-right: 24px; |
|||
font-size: 14px; |
|||
font-family: 'font_bold'; |
|||
color: #84754e; |
|||
font-weight: 700; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.intro-scroll { |
|||
position: absolute; |
|||
top: 298px; |
|||
left: 852px; |
|||
z-index: 1; |
|||
overflow: hidden; |
|||
width: 722px; |
|||
height: 165px; |
|||
padding-right: 14px; |
|||
.intro { |
|||
font-size: 14px; |
|||
font-family: 'font_regular'; |
|||
text-align: justify; |
|||
white-space: pre-wrap; |
|||
color: #736661; |
|||
line-height: 200%; |
|||
:deep(img) { |
|||
width: 100%; |
|||
} |
|||
} |
|||
} |
|||
.go { |
|||
position: absolute; |
|||
top: 38px; |
|||
right: -75px; |
|||
z-index: 1; |
|||
width: 150px; |
|||
img { |
|||
position: absolute; |
|||
width: 150px; |
|||
} |
|||
h5 { |
|||
position: absolute; |
|||
right: 0; |
|||
left: 0; |
|||
display: block; |
|||
margin: 85px auto 0; |
|||
font-size: 22px; |
|||
font-family: 'font_bold'; |
|||
text-align: center; |
|||
color: #faeba9; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
} |
|||
} |
|||
.exit { |
|||
position: absolute; |
|||
top: -60px; |
|||
right: 0; |
|||
img { |
|||
width: 60px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,8 +1,13 @@ |
|||
import { request } from '@/http/http' |
|||
import type { GroupList, BrandRes } from './types' |
|||
import type { GroupList, BrandRes, starPara } from './types' |
|||
|
|||
export const getBrandInfo = () => request<BrandRes>({ url: `/JSON/getBrandShopList.json` }) |
|||
|
|||
export const getShopListByFloor = () => request<{ list: GroupList }>({ url: `/JSON/getBrandShopListByFloor.json` }) |
|||
|
|||
export const getShopListByIndustry = () => request<{ list: GroupList }>({ url: `/JSON/getBrandShopListByIndustryId.json` }) |
|||
|
|||
//点击喜欢按钮
|
|||
export const setBrandStar = (data: starPara) => request<{ code: number }>({ url: `/api/guide/v1/web/setBrandStar`, data, method: 'get' }) |
|||
//获取喜欢按钮
|
|||
export const getBrandStar = (data: starPara) => request({ url: `/api/guide/v1/web/getBrandStar`, data, method: 'get' }) |
|||
|
|||