@ -1 +1,25 @@ |
|||
{"code":200,"msg":"success","data":{"machineCode":"orZRFkOwWYOpbLImEwpjg","machineName":"CS","machineTypeName":"导视","label":"windows","screenAttribute":"1080*1920竖屏","building":"A栋","buildingCode":"DLvmtzN2qodUq_oYr7vyM","buildingOrder":0,"floor":"L1","floorCode":"nL3E-j25zxxkag_HMSGsR","floorOrder":2,"ip":"192.168.1.100","mac":"E0D55E1B2B17","location":"61","angle":"0","projectCode":"project-zert3dski8fqmgr4zhusea","regionCode":"","lensCoordinate":"","orientationCoordinate":""}} |
|||
{ |
|||
"code": 200, |
|||
"msg": "success", |
|||
"data": { |
|||
"machineCode": "orZRFkOwWYOpbLImEwpjg", |
|||
"machineName": "CS", |
|||
"machineTypeName": "导视", |
|||
"label": "windows", |
|||
"screenAttribute": "1080*1920竖屏", |
|||
"building": "A栋", |
|||
"buildingCode": "DLvmtzN2qodUq_oYr7vyM", |
|||
"buildingOrder": 0, |
|||
"floor": "L1", |
|||
"floorCode": "nL3E-j25zxxkag_HMSGsR", |
|||
"floorOrder": 2, |
|||
"ip": "192.168.1.100", |
|||
"mac": "E0D55E1B2B17", |
|||
"location": "61", |
|||
"angle": "0", |
|||
"projectCode": "project-zert3dski8fqmgr4zhusea", |
|||
"regionCode": "", |
|||
"lensCoordinate": "", |
|||
"orientationCoordinate": "" |
|||
} |
|||
} |
|||
|
|||
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 920 B After Width: | Height: | Size: 858 B |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 196 KiB |
|
After Width: | Height: | Size: 918 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 953 B |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 619 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 616 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 587 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 778 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 456 B |
|
After Width: | Height: | Size: 212 B |
|
After Width: | Height: | Size: 791 B |
@ -0,0 +1,118 @@ |
|||
<template> |
|||
<div class="header-container"> |
|||
<div class="left" @click="go"> |
|||
<div class="search-container"> |
|||
<img src="@/assets/images/header/search.svg" alt="" /> |
|||
<div class="line"></div> |
|||
<div> |
|||
<div class="text_zh">搜索</div> |
|||
<div class="text_en">SEARCH</div> |
|||
</div> |
|||
</div> |
|||
<div class="recommend" @click="show"> |
|||
<img class="rem" src="@/assets/images/header/zan.svg" alt="" /> |
|||
<div>{{ $t('header.recommend') }}</div> |
|||
</div> |
|||
</div> |
|||
<div class="right"> |
|||
<WeaAndTime /> |
|||
<img class="logo" src="@/assets/images/header/logo.svg" alt="" /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { useRootStore } from '@/store/root' |
|||
import WeaAndTime from './WeaAndTime.vue' |
|||
|
|||
const store = useRootStore() |
|||
|
|||
function go() { |
|||
store.SET_SHOW_SEARCH(true) |
|||
} |
|||
|
|||
// 展示推荐弹窗 |
|||
function show() { |
|||
store.SET_SHOW_COLUMNLIST(true) |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.header-container { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: 999; |
|||
|
|||
@include fl(space-between); |
|||
|
|||
width: 1920px; |
|||
height: 120px; |
|||
padding: 44px 56px 4px; |
|||
.left { |
|||
@include fl(); |
|||
.search-container { |
|||
@include fl(); |
|||
|
|||
width: 332px; |
|||
height: 72px; |
|||
padding: 16px 0 16px 32px; |
|||
margin-right: 12px; |
|||
background: rgb(255 255 255 / 40%); |
|||
border: 2px solid #fff; |
|||
border-radius: 24px; |
|||
img { |
|||
width: 40px; |
|||
height: 40px; |
|||
} |
|||
.line { |
|||
width: 1px; |
|||
height: 24px; |
|||
margin: 0 16px; |
|||
background: rgb(0 0 0 / 20%); |
|||
} |
|||
.text_zh { |
|||
font-size: 20px; |
|||
font-family: 'font_regular'; |
|||
color: #534f46; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 28px; |
|||
} |
|||
.text_en { |
|||
font-size: 12px; |
|||
font-family: 'font_regular'; |
|||
color: #615c59; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 14px; |
|||
} |
|||
} |
|||
.recommend { |
|||
height: 72px; |
|||
padding: 13px 24px; |
|||
font-size: 10px; |
|||
font-family: 'font_regular'; |
|||
text-align: center; |
|||
color: #615c59; |
|||
background: rgb(255 255 255 / 30%); |
|||
border: 2px solid #fff; |
|||
border-radius: 24px; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 10px; |
|||
.rem { |
|||
width: 32px; |
|||
height: 32px; |
|||
} |
|||
} |
|||
} |
|||
.right { |
|||
@include fl(); |
|||
.logo { |
|||
width: 188px; |
|||
height: 40px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,77 @@ |
|||
<template> |
|||
<div class="header-right"> |
|||
<div class="weather"> |
|||
<div :class="icon.icon" class="iconfont size"></div> |
|||
<div>{{ weather.temperatureNow }}°</div> |
|||
</div> |
|||
<div class="line"></div> |
|||
<div class="time"> |
|||
<p class="current">{{ currentTime }}</p> |
|||
<div class="year"> |
|||
<div>{{ formatDay(date) }}</div> |
|||
<div style="line-height: 12px">{{ whichWeek }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { useTime } from '@/composables/useTime' |
|||
import { useDay } from '@/composables/useDay' |
|||
import { useWeather } from '@/composables/useWeather' |
|||
import { formatDay } from '@/utils/utils' |
|||
|
|||
const { weather, icon } = useWeather() |
|||
const { currentTime } = useTime() |
|||
const { date, whichWeek } = useDay() |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.header-right { |
|||
@include fl(); |
|||
|
|||
height: 36px; |
|||
margin-right: 56px; |
|||
.weather { |
|||
@include fl(); |
|||
|
|||
font-size: 24px; |
|||
font-family: 'font_bold'; |
|||
color: #534f46; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
line-height: 34px; |
|||
.size { |
|||
margin-right: 8px; |
|||
font-size: 32px; |
|||
color: #8e9090; |
|||
} |
|||
} |
|||
.line { |
|||
width: 1px; |
|||
height: 20px; |
|||
margin: 0 24px; |
|||
background: rgb(0 0 0 / 20%); |
|||
} |
|||
.time { |
|||
@include fl(); |
|||
|
|||
.current { |
|||
margin-right: 12px; |
|||
font-size: 24px; |
|||
font-family: 'font_bold'; |
|||
color: #534f46; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
line-height: 34px; |
|||
} |
|||
.year { |
|||
font-size: 10px; |
|||
font-family: 'font_bold'; |
|||
color: #615c59; |
|||
font-weight: 700; |
|||
line-height: 14px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,182 @@ |
|||
<template> |
|||
<div class="menu-container"> |
|||
<div class="language-items"> |
|||
<div class="language-item" :class="{ active: language === 'zh' }" @click="changeLang('zh')">中</div> |
|||
<div class="language-item" :class="{ active: language === 'en' }" @click="changeLang('en')">EN</div> |
|||
</div> |
|||
<div class="menus"> |
|||
<div v-for="item in list" :key="item.title" class="menu" :class="route.fullPath === item.path && 'ac'" @click="go(item)"> |
|||
<img :src="item.icon" alt="" /> |
|||
<div> |
|||
<div class="title" :class="route.fullPath === item.path && 'act'">{{ item.title }}</div> |
|||
<div class="titleEn">{{ item.titleEn }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { storeToRefs } from 'pinia' |
|||
import { useRoute, useRouter } from 'vue-router' |
|||
import { useRootStore } from '@/store/root' |
|||
import { useStatisticsModel } from '@/composables/useStatistics' |
|||
const store = useRootStore() |
|||
const { language } = storeToRefs(store) |
|||
|
|||
function changeLang(lang: Language) { |
|||
if (lang === language.value) { |
|||
return |
|||
} |
|||
store.SET_LANGUAGE(lang) |
|||
} |
|||
|
|||
type MenuList = { |
|||
title: string |
|||
titleEn: string |
|||
icon: string |
|||
path: string |
|||
} |
|||
const list: MenuList[] = [ |
|||
{ |
|||
title: '地图导览', |
|||
titleEn: 'MAP', |
|||
icon: require('@/assets/images/menu/map.svg'), |
|||
path: '/' |
|||
}, |
|||
{ |
|||
title: '品牌列表', |
|||
titleEn: 'BRAND', |
|||
icon: require('@/assets/images/menu/brand.svg'), |
|||
path: '/brand' |
|||
}, |
|||
{ |
|||
title: '活动精选', |
|||
titleEn: 'SELECTION', |
|||
icon: require('@/assets/images/menu/activity.svg'), |
|||
path: '/activity' |
|||
}, |
|||
{ |
|||
title: '会员专享', |
|||
titleEn: 'MEMBER', |
|||
icon: require('@/assets/images/menu/member.svg'), |
|||
path: '/member' |
|||
}, |
|||
{ |
|||
title: '自主寻车', |
|||
titleEn: 'PARKING', |
|||
icon: require('@/assets/images/menu/parking.svg'), |
|||
path: '/parking' |
|||
}, |
|||
{ |
|||
title: '贴心服务', |
|||
titleEn: 'SERVICE', |
|||
icon: require('@/assets/images/menu/service.svg'), |
|||
path: '/service' |
|||
}, |
|||
{ |
|||
title: '交通信息', |
|||
titleEn: 'TRAFFIC', |
|||
icon: require('@/assets/images/menu/traffic.svg'), |
|||
path: '/traffic' |
|||
}, |
|||
{ |
|||
title: '艺术装置', |
|||
titleEn: 'ARTWORK', |
|||
icon: require('@/assets/images/menu/art.svg'), |
|||
path: '/art' |
|||
} |
|||
] |
|||
|
|||
const router = useRouter() |
|||
const route = useRoute() |
|||
|
|||
function go(item: MenuList) { |
|||
router.push(item.path) |
|||
useStatisticsModel({ recordType: 1, moduleName: item.title }) |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.menu-container { |
|||
position: fixed; |
|||
bottom: 0; |
|||
left: 0; |
|||
z-index: 999; |
|||
width: 1920px; |
|||
height: 132px; |
|||
background: url('@/assets/images/menu/bg.svg') no-repeat; |
|||
background-size: 100% 100%; |
|||
pointer-events: none; |
|||
& > * { |
|||
pointer-events: all; |
|||
} |
|||
.language-items { |
|||
@include fl(); |
|||
|
|||
position: absolute; |
|||
top: 82px; |
|||
left: 60px; |
|||
.language-item { |
|||
@include fl(center); |
|||
|
|||
width: 40px; |
|||
height: 36px; |
|||
font-size: 16px; |
|||
font-family: 'font_regular'; |
|||
color: #615c59; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
&.active { |
|||
color: #e00068; |
|||
background: #fff; |
|||
border-radius: 16px; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.menus { |
|||
@include fl(); |
|||
|
|||
position: absolute; |
|||
top: 16px; |
|||
left: 508px; |
|||
.menu { |
|||
@include fl(center); |
|||
|
|||
width: 168px; |
|||
height: 96px; |
|||
margin-right: 4px; |
|||
color: #534f46; |
|||
img { |
|||
width: 44px; |
|||
height: 44px; |
|||
margin-right: 12px; |
|||
} |
|||
.title { |
|||
font-size: 16px; |
|||
font-family: 'font_regular'; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 24px; |
|||
} |
|||
.titleEn { |
|||
margin-top: 2px; |
|||
font-size: 12px; |
|||
font-family: 'font_regular'; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 14px; |
|||
} |
|||
} |
|||
.ac { |
|||
color: #fff; |
|||
background: #e00068; |
|||
border-radius: 40px 8px; |
|||
img { |
|||
filter: grayscale(1) brightness(800%); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,90 @@ |
|||
<template> |
|||
<div class="shop-container" @click="showDetail(shop)"> |
|||
<div class="top"> |
|||
<img :src="shop.logoUrl ? shop.logoUrl : require('@/assets/images/header/logo.svg')" class="logo" alt="" /> |
|||
</div> |
|||
<div class="bottom"> |
|||
<div class="shop-name">{{ switchLanguage(shop, 'shopName') }}</div> |
|||
<div class="right"> |
|||
<img v-if="shop.industryUrl" :src="shop.industryUrl" alt="" /> |
|||
<div class="ins">{{ shop.floor }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { useRootStore } from '@/store/root' |
|||
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
|||
interface Prop { |
|||
shop: Shop |
|||
} |
|||
|
|||
defineProps<Prop>() |
|||
const { switchLanguage } = useSwitchLanguage() |
|||
const store = useRootStore() |
|||
function showDetail(shop: Shop) { |
|||
store.SET_SHOP(shop) |
|||
store.SET_SHOW_DETAIL(true) |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.shop-container { |
|||
width: 212px; |
|||
height: 176px; |
|||
background: #fff; |
|||
border-radius: 16px; |
|||
.top { |
|||
@include fl(center); |
|||
|
|||
position: relative; |
|||
width: 212px; |
|||
height: 136px; |
|||
border-radius: 16px 16px 0 0; |
|||
.logo { |
|||
width: 150px; |
|||
height: 150px; |
|||
object-fit: scale-down; |
|||
} |
|||
} |
|||
.bottom { |
|||
@include fl(space-between); |
|||
|
|||
width: 212px; |
|||
height: 40px; |
|||
padding: 9px 16px; |
|||
background: rgb(255 255 255 / 60%); |
|||
border-radius: 0 0 16px 16px; |
|||
.shop-name { |
|||
@include no-wrap; |
|||
|
|||
max-width: 120px; |
|||
font-size: 14px; |
|||
font-family: 'font_bold'; |
|||
color: #534f46; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
line-height: 22px; |
|||
} |
|||
.right { |
|||
@include fl; |
|||
|
|||
img { |
|||
width: 16px; |
|||
height: 16px; |
|||
margin-right: 8px; |
|||
} |
|||
|
|||
.ins { |
|||
font-size: 14px; |
|||
font-family: 'font_bold'; |
|||
color: #615c59; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
line-height: 22px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,19 @@ |
|||
import { ref, shallowRef, toRefs } from 'vue' |
|||
import { useRootStore } from '@/store/root' |
|||
import { hideMapDialog } from '@/composables/useInitMap' |
|||
export const useArea = () => { |
|||
const store = useRootStore() |
|||
const { shopList, device } = toRefs(store) |
|||
|
|||
const areaName = ref('全部区域') //楼层选中索引
|
|||
const selectedShopListA = shallowRef<Shop[]>(shopList.value.filter(item => item.floor === device.value.floor)) //选中楼层的店铺列表
|
|||
|
|||
// 切换楼层
|
|||
function changeArea(name: string) { |
|||
areaName.value = name |
|||
selectedShopListA.value = shopList.value.filter(item => item.floor === name) |
|||
hideMapDialog() |
|||
} |
|||
|
|||
return { areaName, selectedShopListA, changeArea } |
|||
} |
|||
@ -1,22 +1,20 @@ |
|||
import { ref, shallowRef, toRefs } from 'vue' |
|||
import { useRootStore } from '@/store/root' |
|||
|
|||
import { hideMapDialog } from '@/composables/useInitMap' |
|||
export const useGuideFilterShop = () => { |
|||
const store = useRootStore() |
|||
const { shopList, currentBuildingFloorsList, device } = toRefs(store) |
|||
|
|||
const floorIdx = ref(-1) //楼层选中索引
|
|||
const selectedShopList = shallowRef<Shop[]>([]) //选中楼层的店铺列表
|
|||
const { shopList, device } = toRefs(store) |
|||
|
|||
function filterShopByFloorName(floorName: string) { |
|||
selectedShopList.value = shopList.value.filter(item => item.floor === floorName) |
|||
} |
|||
const floorIdx = ref(device.value.floorOrder) //楼层选中索引
|
|||
const selectedShopList = shallowRef<Shop[]>(shopList.value.filter(item => item.floor === device.value.floor)) //选中楼层的店铺列表
|
|||
|
|||
// //筛选当前楼层所需数据
|
|||
function filterAboutCurrentInfo() { |
|||
floorIdx.value = currentBuildingFloorsList.value.findIndex(item => item.floor === device.value.floor) |
|||
selectedShopList.value = shopList.value.filter(item => item.floor === device.value.floor) |
|||
// 切换楼层
|
|||
function changeFloor(floorOrder: number) { |
|||
floorIdx.value = floorOrder |
|||
selectedShopList.value = shopList.value.filter(item => item.floorOrder === floorOrder) |
|||
hideMapDialog() |
|||
window.Map_QM.showFloor(floorOrder) |
|||
} |
|||
|
|||
return { floorIdx, selectedShopList, filterShopByFloorName, filterAboutCurrentInfo } |
|||
return { floorIdx, selectedShopList, changeFloor } |
|||
} |
|||
|
|||
@ -1,7 +1,7 @@ |
|||
import { request } from '../../http' |
|||
import type { Query } from './types' |
|||
import { getPrefixUrl } from '../../http' |
|||
|
|||
import type { Query, Clickquery } from './types' |
|||
//数据统计
|
|||
export const getStatistics = (data: Query) => |
|||
request({ url: `${getPrefixUrl().interfaceUrl}/analysis/v1/web/deviceUseClickDataUpload`, data, method: 'post' }) |
|||
export const getStatistics = (data: Query) => request({ url: `/analysis/v1/web/deviceUseClickDataUpload`, data, method: 'post' }) |
|||
|
|||
//数据统计(模块点击、活动点击、使用人次点击)
|
|||
export const getGuideClickDataUpload = (data: Clickquery) => request({ url: '/analysis/v1/web/guideClickDataUpload', data, method: 'post' }) |
|||
|
|||
@ -0,0 +1,68 @@ |
|||
<template> |
|||
<div class="area-container"> |
|||
<div |
|||
v-for="(item, index) in areaList" |
|||
:key="item" |
|||
class="area" |
|||
:class="{ ac: item === areaName, area1: index === 0 }" |
|||
@click="changeArea(item)" |
|||
> |
|||
<div :class="{ w1: index === 0 }">{{ item }}</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
const areaList = ['全部区域', 'SKP', 'K大道', '美食大道', 'SKP-S'] |
|||
|
|||
interface Prop { |
|||
areaName: string |
|||
} |
|||
|
|||
defineProps<Prop>() |
|||
const emit = defineEmits(['changeArea']) |
|||
function changeArea(name: string) { |
|||
emit('changeArea', name) |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.area-container { |
|||
position: fixed; |
|||
top: 252px; |
|||
left: 536px; |
|||
z-index: 999; |
|||
width: 74px; |
|||
height: 400px; |
|||
background: rgb(255 255 255 / 30%); |
|||
border: 2px solid #fff; |
|||
border-radius: 24px; |
|||
backdrop-filter: blur(11px); |
|||
.area { |
|||
@include fl(center); |
|||
|
|||
width: 72px; |
|||
height: 80px; |
|||
font-size: 14px; |
|||
font-family: 'font_bold'; |
|||
color: #534f46; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
line-height: 22px; |
|||
.w1 { |
|||
width: 28px; |
|||
} |
|||
} |
|||
|
|||
.area1 { |
|||
margin: -1px; |
|||
background: rgb(255 255 255 / 50%); |
|||
border: 2px solid #fff; |
|||
border-radius: 24px; |
|||
backdrop-filter: blur(11px); |
|||
} |
|||
.ac { |
|||
color: #e00068; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,120 @@ |
|||
<template> |
|||
<div class="art-list"> |
|||
<Transition |
|||
mode="out-in" |
|||
appear |
|||
enter-active-class="animate__animated animate__fadeIn" |
|||
leave-active-class="animate__animated animate__fadeOut" |
|||
> |
|||
<ScrollView v-if="artList.length !== 0" class="myScroll" :list="artList" :pull-up="false"> |
|||
<div class="lists"> |
|||
<div v-for="(item, index) in artList" :key="item.name" class="item"> |
|||
<div class="order">{{ index + 1 }}</div> |
|||
<div> |
|||
<div class="name">{{ item.name }}</div> |
|||
<div class="nameEn">{{ item.nameEn }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</ScrollView> |
|||
<img v-else src="@/assets/images/stay_tuned.svg" alt="" /> |
|||
</Transition> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import ScrollView from '@/base/ScrollView/ScrollView.vue' |
|||
const artList = [ |
|||
{ |
|||
name: '花之泉广场', |
|||
nameEn: 'NORTH ENTRANCE FOUNTAIN SQUARE' |
|||
}, |
|||
{ |
|||
name: '花之泉广场', |
|||
nameEn: 'NORTH ENTRANCE FOUNTAIN SQUARE' |
|||
}, |
|||
{ |
|||
name: '花之泉广场', |
|||
nameEn: 'NORTH ENTRANCE FOUNTAIN SQUARE' |
|||
}, |
|||
{ |
|||
name: '花之泉广场', |
|||
nameEn: 'NORTH ENTRANCE FOUNTAIN SQUARE' |
|||
}, |
|||
{ |
|||
name: '花之泉广场', |
|||
nameEn: 'NORTH ENTRANCE FOUNTAIN SQUARE' |
|||
}, |
|||
{ |
|||
name: '花之泉广场', |
|||
nameEn: 'NORTH ENTRANCE FOUNTAIN SQUARE' |
|||
}, |
|||
{ |
|||
name: '花之泉广场', |
|||
nameEn: 'NORTH ENTRANCE FOUNTAIN SQUARE' |
|||
} |
|||
] |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.art-list { |
|||
@include fl(center); |
|||
|
|||
position: fixed; |
|||
top: 232px; |
|||
left: 56px; |
|||
z-index: 998; |
|||
width: 396px; |
|||
height: 783px; |
|||
.myScroll { |
|||
overflow: hidden; |
|||
height: 783px; |
|||
.lists { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr; |
|||
gap: 24px; |
|||
grid-auto-flow: row; |
|||
.item { |
|||
@include fl(flex-start, flex-start); |
|||
|
|||
width: 186px; |
|||
height: 28px; |
|||
.order { |
|||
width: 24px; |
|||
height: 24px; |
|||
padding: 1px 8px; |
|||
margin-right: 10px; |
|||
font-size: 14px; |
|||
font-family: 'font_regular'; |
|||
text-align: center; |
|||
color: var(--unnamed, #534f46); |
|||
background: #ceb9ab; |
|||
border-radius: 18px; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 22px; |
|||
} |
|||
|
|||
.name { |
|||
margin-bottom: 2px; |
|||
font-size: 12px; |
|||
font-family: 'font_regular'; |
|||
color: #534f46; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 14px; |
|||
} |
|||
|
|||
.nameEn { |
|||
font-size: 8px; |
|||
font-family: 'font_regular'; |
|||
color: #615c59; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 12px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,77 @@ |
|||
<template> |
|||
<div class="floor-list"> |
|||
<div class="floor all" :class="floorIdx === -1 && 'ac'" @click="changeFloor(-1)"> |
|||
<div class="name">ALL</div> |
|||
</div> |
|||
<div |
|||
v-for="item in currentBuildingFloorsList" |
|||
:key="item.floorCode" |
|||
class="floor" |
|||
:class="floorIdx === item.floorOrder && 'ac'" |
|||
@click="changeFloor(item.floorOrder)" |
|||
> |
|||
<div class="name">{{ item.floor }}</div> |
|||
<img v-if="item.floorOrder === device.floorOrder" src="@/assets/images/guide/point.svg" alt="" /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { useRootStore } from '@/store/root' |
|||
import { toRefs } from 'vue' |
|||
|
|||
interface Prop { |
|||
floorIdx: number |
|||
} |
|||
|
|||
defineProps<Prop>() |
|||
const emit = defineEmits(['changeFloor']) |
|||
const store = useRootStore() |
|||
const { currentBuildingFloorsList, device } = toRefs(store) |
|||
function changeFloor(floorOrder: number) { |
|||
emit('changeFloor', floorOrder) |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.floor-list { |
|||
position: fixed; |
|||
top: 152px; |
|||
right: 50px; |
|||
z-index: 999; |
|||
.floor { |
|||
@include fl(center); |
|||
|
|||
position: relative; |
|||
width: 72px; |
|||
height: 86px; |
|||
margin-bottom: 8px; |
|||
color: #534f46; |
|||
background: rgb(255 255 255 / 50%); |
|||
border: 2px solid #fff; |
|||
border-radius: 24px; |
|||
backdrop-filter: blur(11px); |
|||
.name { |
|||
font-size: 18px; |
|||
font-family: 'font_bold'; |
|||
text-align: center; |
|||
font-style: normal; |
|||
font-weight: 700; |
|||
} |
|||
img { |
|||
position: absolute; |
|||
top: 12px; |
|||
right: 10px; |
|||
width: 16px; |
|||
height: 16px; |
|||
} |
|||
} |
|||
.all { |
|||
height: 72px; |
|||
} |
|||
.ac { |
|||
color: #fff; |
|||
background: #e00068; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,36 @@ |
|||
<template> |
|||
<div class="floor-pic-list"> |
|||
<div v-for="item in currentBuildingFloorsList" :key="item.floorCode" class="floor"> |
|||
<img :src="item.floorMapUrl" alt="" /> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { useRootStore } from '@/store/root' |
|||
import { toRefs } from 'vue' |
|||
const store = useRootStore() |
|||
const { currentBuildingFloorsList } = toRefs(store) |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.floor-pic-list { |
|||
position: fixed; |
|||
top: 232px; |
|||
right: 50px; |
|||
z-index: 998; |
|||
.floor { |
|||
width: 296px; |
|||
height: 86px; |
|||
padding: 3px 0; |
|||
margin-bottom: 8px; |
|||
background: linear-gradient(270deg, rgb(138 118 106 / 10%) 0%, rgb(138 118 106 / 0%) 100%); |
|||
border: 2px solid #fff; |
|||
border-radius: 0 24px 24px 0; |
|||
img { |
|||
width: 200px; |
|||
height: 80px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -1,13 +1,359 @@ |
|||
<template> |
|||
<div class="guide-container"></div> |
|||
<div class="guide-container"> |
|||
<!-- 楼层列表 --> |
|||
<Transition appear enter-active-class="animate__animated animate__fadeInRight"> |
|||
<Floor :floor-idx="floorIdx" @change-floor="changeFloor" /> |
|||
</Transition> |
|||
|
|||
<!-- 区域列表 --> |
|||
<Transition appear enter-active-class="animate__animated animate__fadeIn"> |
|||
<Area v-if="floorIdx !== -1" :area-name="areaName" @change-area="changeArea" /> |
|||
</Transition> |
|||
|
|||
<!-- 店铺列表 --> |
|||
<ShopList v-if="floorIdx !== -1" :list="selectedShopList" /> |
|||
|
|||
<!-- 设备 --> |
|||
<Transition appear enter-active-class="animate__animated animate__fadeIn"> |
|||
<div v-if="floorIdx !== -1" class="fac"> |
|||
<ScrollView :list="facilityList" :scroll-x="true" class="art-myScroll"> |
|||
<div style="display: inline-block"> |
|||
<div class="artList"> |
|||
<div v-for="item in artPlaceList" :key="item.name" class="art-item"> |
|||
<img class="logo" :src="item.icon" alt="" /> |
|||
<div class="name">{{ switchLanguage(item, 'name') }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</ScrollView> |
|||
<div class="faclists"> |
|||
<div v-for="(item, index) in list" :key="item.name" class="reset-dir" @click="handleMapIcon(item, index)"> |
|||
<div class="top" :class="mapIdx === index && 'ac'"> |
|||
<img :src="item.icon" alt="" /> |
|||
</div> |
|||
<div class="txt">{{ switchLanguage(item, 'name') }}</div> |
|||
</div> |
|||
<div class="line"></div> |
|||
<ScrollView :list="facilityList" :scroll-x="true" class="myScroll"> |
|||
<div style="display: inline-block"> |
|||
<div class="faclist"> |
|||
<div v-for="item in facilityList" :key="item.code" class="fac-item" @click="handleFacility(item)"> |
|||
<img class="logo" :src="item.filePath" alt="" /> |
|||
<div class="name">{{ switchLanguage(item, 'name') }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</ScrollView> |
|||
</div> |
|||
</div> |
|||
<div v-else class="art-fac"> |
|||
<ScrollView :list="facilityList" :scroll-x="true" class="myScroll"> |
|||
<div style="display: inline-block"> |
|||
<div class="art-faclist"> |
|||
<div v-for="item in facilityList" :key="item.code" class="art-fac-item" @click="handleFacility(item)"> |
|||
<img class="logo" :src="item.filePath" alt="" /> |
|||
<div> |
|||
<div class="name">{{ item.name }}</div> |
|||
<div class="nameEn">{{ item.nameEn }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</ScrollView> |
|||
</div> |
|||
</Transition> |
|||
|
|||
<!-- 手势 --> |
|||
<Transition appear enter-active-class="animate__animated animate__fadeIn"> |
|||
<img v-if="language === 'zh'" class="point" src="@/assets/images/guide/tip_zh.svg" alt="" /> |
|||
<img v-else class="point" src="@/assets/images/guide/tip_en.svg" alt="" /> |
|||
</Transition> |
|||
|
|||
<!-- 区域缩略图 --> |
|||
<Transition appear enter-active-class="animate__animated animate__fadeIn"> |
|||
<img v-if="floorIdx !== -1" class="area" src="@/assets/images/guide/area_emp.svg" alt="" /> |
|||
</Transition> |
|||
|
|||
<!-- 人行道等 --> |
|||
<Transition appear enter-active-class="animate__animated animate__fadeIn"> |
|||
<Place v-if="floorIdx === -1" /> |
|||
</Transition> |
|||
|
|||
<!-- 艺术品列表 --> |
|||
<ArtList v-if="floorIdx === -1" /> |
|||
|
|||
<!-- 楼层缩略图 --> |
|||
<div v-if="floorIdx === -1" class="floor-pic-list"> |
|||
<div |
|||
v-for="(item, index) in floorlist" |
|||
:key="index" |
|||
class="floor animate__animated animate__fadeIn" |
|||
:style="{ animationDelay: index / 5 + 's' }" |
|||
> |
|||
<img :src="item" alt="" /> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import { toRefs } from 'vue' |
|||
import { useRootStore } from '@/store/root' |
|||
import { useGuideMapOperation } from '@/composables/useGuideMapOperation' |
|||
import { useFacilityNav } from '@/composables/useFacilityNav' |
|||
import { useGuideFilterShop } from '@/composables/useGuideFilterShop' |
|||
import { useSwitchLanguage } from '@/composables/useSwitchLanguage' |
|||
import { useArea } from '@/composables/useArea' |
|||
import ScrollView from '@/base/ScrollView/ScrollView.vue' |
|||
import Floor from './Floor.vue' |
|||
import Area from './Area.vue' |
|||
import ShopList from './ShopList.vue' |
|||
import Place from './Place.vue' |
|||
import ArtList from './ArtList.vue' |
|||
|
|||
const { floorIdx, selectedShopList, filterShopByFloorName, filterAboutCurrentInfo } = useGuideFilterShop() //筛选楼层 |
|||
const { switchFloor, handleMapIcon, list, mapIdx } = useGuideMapOperation() //复位 位置等操作 |
|||
const store = useRootStore() |
|||
const { switchLanguage } = useSwitchLanguage() |
|||
const { language, facilityList } = toRefs(store) |
|||
const { floorIdx, selectedShopList, changeFloor } = useGuideFilterShop() //筛选楼层 |
|||
const { areaName, selectedShopListA, changeArea } = useArea() //筛选楼层 |
|||
const { handleMapIcon, list, mapIdx } = useGuideMapOperation() //复位 位置等操作 |
|||
const { handleFacility } = useFacilityNav() //公共设施导航 |
|||
// handleMapIcon(list[1], 1) |
|||
const floorlist = [ |
|||
require('@/assets/images/guide/minMap.svg'), |
|||
require('@/assets/images/guide/minMap.svg'), |
|||
require('@/assets/images/guide/minMap.svg'), |
|||
require('@/assets/images/guide/minMap.svg'), |
|||
require('@/assets/images/guide/minMap.svg'), |
|||
require('@/assets/images/guide/minMap.svg') |
|||
] |
|||
|
|||
const artPlaceList = [ |
|||
{ |
|||
name: '猩猩的太空漫步', |
|||
nameEn: 'dddd', |
|||
icon: '' |
|||
}, |
|||
{ |
|||
name: '共生', |
|||
nameEn: 'dddd', |
|||
icon: '' |
|||
}, |
|||
{ |
|||
name: '超新星', |
|||
nameEn: 'dddd', |
|||
icon: '' |
|||
}, |
|||
{ |
|||
name: '盛开的山谷', |
|||
nameEn: 'dddd', |
|||
icon: '' |
|||
}, |
|||
{ |
|||
name: '琥珀', |
|||
nameEn: 'dddd', |
|||
icon: '' |
|||
} |
|||
] |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.guide-container { |
|||
.fac { |
|||
@include fl(space-between); |
|||
|
|||
position: fixed; |
|||
bottom: 132px; |
|||
left: 488px; |
|||
z-index: 999; |
|||
width: 1432px; |
|||
height: 120px; |
|||
padding: 26px 56px 0 48px; |
|||
background: linear-gradient(275deg, rgb(255 255 255 / 40%) 0%, rgb(255 255 255 / 8%) 80.56%, rgb(255 255 255 / 0%) 100%); |
|||
.art-myScroll { |
|||
overflow: hidden; |
|||
max-width: 340px; |
|||
.artList { |
|||
@include fl(flex-start, flex-start); |
|||
.art-item { |
|||
margin-right: 16px; |
|||
text-align: center; |
|||
.logo { |
|||
width: 44px; |
|||
height: 44px; |
|||
margin-bottom: 6px; |
|||
border-radius: 14px; |
|||
} |
|||
.name { |
|||
width: 48px; |
|||
font-size: 12px; |
|||
font-family: 'font_regular'; |
|||
text-align: center; |
|||
color: #8e9090; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 12px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.faclists { |
|||
@include fl(flex-start, flex-start); |
|||
.reset-dir { |
|||
width: 48px; |
|||
height: 64px; |
|||
margin-right: 16px; |
|||
text-align: center; |
|||
.top { |
|||
@include fl(center); |
|||
|
|||
width: 44px; |
|||
height: 44px; |
|||
margin-bottom: 6px; |
|||
background: #fff; |
|||
border-radius: 12px; |
|||
img { |
|||
width: 24px; |
|||
height: 24px; |
|||
} |
|||
} |
|||
.ac { |
|||
background: #e00068; |
|||
img { |
|||
filter: grayscale(1) brightness(500%); |
|||
} |
|||
} |
|||
.txt { |
|||
width: 48px; |
|||
font-size: 12px; |
|||
font-family: 'font_regular'; |
|||
text-align: center; |
|||
color: #8e9090; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 12px; |
|||
} |
|||
} |
|||
.line { |
|||
width: 1px; |
|||
height: 32px; |
|||
margin: 0 32px 0 16px; |
|||
background: rgb(0 0 0 / 10%); |
|||
} |
|||
.myScroll { |
|||
overflow: hidden; |
|||
width: 592px; |
|||
.faclist { |
|||
@include fl(flex-start, flex-start); |
|||
.fac-item { |
|||
margin-right: 16px; |
|||
text-align: center; |
|||
.logo { |
|||
width: 44px; |
|||
height: 44px; |
|||
margin-bottom: 6px; |
|||
border-radius: 14px; |
|||
} |
|||
.name { |
|||
width: 48px; |
|||
font-size: 12px; |
|||
font-family: 'font_regular'; |
|||
text-align: center; |
|||
color: #8e9090; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 12px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.art-fac { |
|||
@include fl(center); |
|||
|
|||
position: fixed; |
|||
bottom: 132px; |
|||
left: 488px; |
|||
z-index: 999; |
|||
width: 1432px; |
|||
height: 120px; |
|||
background: linear-gradient(275deg, rgb(255 255 255 / 40%) 0%, rgb(255 255 255 / 8%) 80.56%, rgb(255 255 255 / 0%) 100%); |
|||
.myScroll { |
|||
overflow: hidden; |
|||
max-width: 1343px; |
|||
.art-faclist { |
|||
@include fl(flex-start, flex-start); |
|||
.art-fac-item { |
|||
@include fl(); |
|||
|
|||
margin-right: 40px; |
|||
.logo { |
|||
width: 28px; |
|||
height: 28px; |
|||
margin-right: 8px; |
|||
border-radius: 50%; |
|||
} |
|||
.name { |
|||
font-size: 12px; |
|||
font-family: 'font_regular'; |
|||
white-space: nowrap; |
|||
color: #8e9090; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 14px; |
|||
} |
|||
.nameEn { |
|||
font-size: 8px; |
|||
font-family: 'font_regular'; |
|||
white-space: nowrap; |
|||
color: #615c59; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 12px; |
|||
text-transform: uppercase; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
.point { |
|||
position: fixed; |
|||
top: 40px; |
|||
left: 528px; |
|||
z-index: 999; |
|||
width: 246px; |
|||
height: 80px; |
|||
} |
|||
|
|||
.area { |
|||
position: fixed; |
|||
top: 152px; |
|||
right: 170px; |
|||
z-index: 999; |
|||
width: 256px; |
|||
height: 100px; |
|||
} |
|||
|
|||
.floor-pic-list { |
|||
position: fixed; |
|||
top: 232px; |
|||
right: 50px; |
|||
z-index: 998; |
|||
.floor { |
|||
width: 296px; |
|||
height: 86px; |
|||
padding: 3px 0; |
|||
margin-bottom: 8px; |
|||
background: linear-gradient(270deg, rgb(138 118 106 / 10%) 0%, rgb(138 118 106 / 0%) 100%); |
|||
border-radius: 0 24px 24px 0; |
|||
img { |
|||
width: 200px; |
|||
height: 80px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
|
|||
@ -0,0 +1,75 @@ |
|||
<template> |
|||
<div class="place-container"> |
|||
<div v-for="item in placeList" :key="item.name" class="item"> |
|||
<div |
|||
class="bar" |
|||
:style="{ backgroundColor: item.backgroundColor, borderColor: item.borderColor ? item.borderColor : item.backgroundColor }" |
|||
></div> |
|||
<div> |
|||
<div class="text">{{ item.name }}</div> |
|||
<div class="textEn">{{ item.nameEn }}</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
const placeList = [ |
|||
{ |
|||
name: '车行通道', |
|||
nameEn: 'TRAVEL LANE', |
|||
backgroundColor: '#615C59', |
|||
borderColor: '#615C59' |
|||
}, |
|||
{ |
|||
name: '人行通道', |
|||
nameEn: 'PEDESTRIAN LANE', |
|||
backgroundColor: '#FFF', |
|||
borderColor: '#615C59' |
|||
}, |
|||
{ |
|||
name: '水景', |
|||
nameEn: 'WATERSCAPE', |
|||
backgroundColor: '#61B5D0', |
|||
borderColor: '#61B5D0' |
|||
} |
|||
] |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.place-container { |
|||
@include fl(); |
|||
|
|||
position: fixed; |
|||
top: 152px; |
|||
left: 56px; |
|||
z-index: 999; |
|||
.item { |
|||
@include fl(); |
|||
|
|||
margin-right: 28px; |
|||
.bar { |
|||
width: 45px; |
|||
height: 12px; |
|||
margin-right: 10px; |
|||
border: 1px solid; |
|||
} |
|||
.text { |
|||
font-size: 12px; |
|||
font-family: 'font_bold'; |
|||
color: #615c59; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 14px; |
|||
} |
|||
.textEn { |
|||
font-size: 8px; |
|||
font-family: 'font_regular'; |
|||
color: #8e9090; |
|||
font-style: normal; |
|||
font-weight: 400; |
|||
line-height: 12px; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,49 @@ |
|||
<template> |
|||
<div class="shop-list"> |
|||
<Transition |
|||
mode="out-in" |
|||
appear |
|||
enter-active-class="animate__animated animate__fadeIn" |
|||
leave-active-class="animate__animated animate__fadeOut" |
|||
> |
|||
<ScrollView v-if="list.length !== 0" class="myScroll" :list="list" :pull-up="false"> |
|||
<div class="lists"> |
|||
<ShopItem v-for="item in list" :key="item.shopCode" :shop="item" :type="false" /> |
|||
</div> |
|||
</ScrollView> |
|||
<img v-else src="@/assets/images/stay_tuned.svg" alt="" /> |
|||
</Transition> |
|||
</div> |
|||
</template> |
|||
|
|||
<script setup lang="ts"> |
|||
import ScrollView from '@/base/ScrollView/ScrollView.vue' |
|||
import ShopItem from '@/components/ShopItem/ShopItem.vue' |
|||
interface Prop { |
|||
list: Shop[] |
|||
} |
|||
defineProps<Prop>() |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.shop-list { |
|||
@include fl(center); |
|||
|
|||
position: fixed; |
|||
top: 152px; |
|||
left: 56px; |
|||
z-index: 998; |
|||
width: 432px; |
|||
height: 864px; |
|||
.myScroll { |
|||
overflow: hidden; |
|||
height: 864px; |
|||
.lists { |
|||
display: grid; |
|||
grid-template-columns: 1fr 1fr; |
|||
gap: 8px; |
|||
grid-auto-flow: row; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||