|
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 { 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 getBrandInfo = () => request<BrandRes>({ url: `/JSON/getBrandShopList.json` }) |
||||
|
|
||||
export const getShopListByFloor = () => request<{ list: GroupList }>({ url: `/JSON/getBrandShopListByFloor.json` }) |
export const getShopListByFloor = () => request<{ list: GroupList }>({ url: `/JSON/getBrandShopListByFloor.json` }) |
||||
|
|
||||
export const getShopListByIndustry = () => request<{ list: GroupList }>({ url: `/JSON/getBrandShopListByIndustryId.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' }) |
||||
|
|||||