Browse Source

Merge branch 'dev' of company:project-shenyangk11/sy_k11_H_base_daoshi_vue_ts into dev

pull/2/head
deepblues 3 years ago
parent
commit
912340ecfa
  1. 138
      public/static/offline/JSON/getArtList.json
  2. 34
      public/static/offline/JSON/getModuleList.json
  3. 38
      src/components/CarInfo/CarInfo.vue
  4. 5
      src/components/Carousel/Carousel.vue
  5. 48
      src/components/Menu/Menu.vue
  6. 26
      src/components/PlateInput/PlateInput.vue
  7. 4
      src/components/Search/Hot.vue
  8. 4
      src/components/Search/Result.vue
  9. 2
      src/components/ShopDetail/ShopDetail.vue
  10. 11
      src/components/Traffic/Traffic.vue
  11. 27
      src/composables/useActivityNav.ts
  12. 4
      src/composables/useFacilityNav.ts
  13. 72
      src/composables/useFindCar.ts
  14. 3
      src/composables/useHandleScreen.ts
  15. 25
      src/composables/useInitConfigAndMallInfo.ts
  16. 4
      src/composables/useParkingKeyboard.ts
  17. 37
      src/composables/useStatistics.ts
  18. 12
      src/enums/index.ts
  19. 10
      src/http/api/activity/index.ts
  20. 4
      src/http/api/base/index.ts
  21. 4
      src/http/api/home/index.ts
  22. 3
      src/http/api/member/index.ts
  23. 5
      src/http/api/statistics/index.ts
  24. 9
      src/http/api/statistics/types.ts
  25. 9
      src/store/root/actions.ts
  26. 7
      src/store/root/state.ts
  27. 8
      src/types/activity.d.ts
  28. 4
      src/types/car.d.ts
  29. 2
      src/types/map.d.ts
  30. 4
      src/types/menu.d.ts
  31. 16
      src/views/Activity/Activity.vue
  32. 3
      src/views/Brand/Brand.vue
  33. 37
      src/views/Index/Middle.vue
  34. 49
      src/views/Member/Member.vue
  35. 3
      src/views/Nav/Nav.vue
  36. 15
      src/views/Parking/Parking.vue
  37. 16
      src/views/School/School.vue

138
public/static/offline/JSON/getArtList.json

@ -0,0 +1,138 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"fileCode": "U7L-31evFSZcHT-Cx_afU",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/U7L-31evFSZcHT-Cx_afU.jpg",
"flag": 2,
"artType": 2
},
{
"fileCode": "8eaU9Xr1gng_VA_J93wY4",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/8eaU9Xr1gng_VA_J93wY4.jpg",
"flag": 2,
"artType": 2
},
{
"fileCode": "waeW0L9rBMK2cgKfYq9p6",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/waeW0L9rBMK2cgKfYq9p6.jpg",
"flag": 2,
"artType": 2
},
{
"fileCode": "XWzK3bNnd4G7ZqvP3jKVC",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/XWzK3bNnd4G7ZqvP3jKVC.png",
"flag": 1,
"artType": 2
},
{
"fileCode": "wmDoGzz91VdkWXk21w3vc",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/wmDoGzz91VdkWXk21w3vc.png",
"flag": 1,
"artType": 2
},
{
"fileCode": "Tbbv6-r31zJ-nb_IwuCni",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/Tbbv6-r31zJ-nb_IwuCni.png",
"flag": 2,
"artType": 4
},
{
"fileCode": "rKqs6tfSx-YE9mVRs6jRH",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/rKqs6tfSx-YE9mVRs6jRH.png",
"flag": 1,
"artType": 4
},
{
"fileCode": "WeRFpcfjtc6se7VVlulv9",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/WeRFpcfjtc6se7VVlulv9.png",
"flag": 1,
"artType": 4
},
{
"fileCode": "9BB20uH7LsAUCs9G5bLn1",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/9BB20uH7LsAUCs9G5bLn1.jpeg",
"flag": 1,
"artType": 1
},
{
"fileCode": "xyU-DUq-t_RrrDIuzsVaA",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/xyU-DUq-t_RrrDIuzsVaA.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "sp9psNqTdHdvB_Hrjkoi_",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/sp9psNqTdHdvB_Hrjkoi_.png",
"flag": 1,
"artType": 1
},
{
"fileCode": "PDUU-eWClnBaf75GvkLtl",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230505/PDUU-eWClnBaf75GvkLtl.png",
"flag": 1,
"artType": 3
},
{
"fileCode": "Gb1NiXqSAxQkdd2izaPJO",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/Gb1NiXqSAxQkdd2izaPJO.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "Fmk6kcf07YcAJp7sw2ZQb",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/Fmk6kcf07YcAJp7sw2ZQb.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "4oeWRq44Yib1ZLJv--7XX",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/4oeWRq44Yib1ZLJv--7XX.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "WO3JKVPWJ_y82uNR-p2nA",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/WO3JKVPWJ_y82uNR-p2nA.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "MRSnm9ILLTcU5R_ILNipY",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/MRSnm9ILLTcU5R_ILNipY.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "KtAw80_3z8nCffxts0eGB",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/KtAw80_3z8nCffxts0eGB.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "Z-KsfCiytrn3_5cj__5KY",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/Z-KsfCiytrn3_5cj__5KY.png",
"flag": 2,
"artType": 1
},
{
"fileCode": "Hve3AxoPDuLx42ObwtW76",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/Hve3AxoPDuLx42ObwtW76.png",
"flag": 2,
"artType": 2
},
{
"fileCode": "u-LrcbOriATjX4QeX2FJq",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/u-LrcbOriATjX4QeX2FJq.png",
"flag": 1,
"artType": 2
},
{
"fileCode": "PMUBs8-cvNM9FqzO1Ozyx",
"fileUrl": "/iotFile/project-bffju2pfalsylhcfcuzgaa/20230506/PMUBs8-cvNM9FqzO1Ozyx.png",
"flag": 1,
"artType": 2
}
]
}

34
public/static/offline/JSON/getModuleList.json

@ -0,0 +1,34 @@
{
"code": 200,
"msg": "操作成功",
"data": [
{
"moduleName": "主页",
"status": 0
},
{
"moduleName": "店铺导航",
"status": 0
},
{
"moduleName": "优惠与活动",
"status": 0
},
{
"moduleName": "会员专享",
"status": 0
},
{
"moduleName": "服务",
"status": 0
},
{
"moduleName": "停车与缴费",
"status": 0
},
{
"moduleName": "文化学院",
"status": 0
}
]
}

38
src/components/CarInfo/CarInfo.vue

@ -2,19 +2,19 @@
<div class="car-info-wrapper">
<div class="masker" @click="close"></div>
<div class="car-content">
<img src="" class="car-img" alt="" />
<img :src="carInfo.carImage" class="car-img" alt="" />
<div class="car">
<div class="car-group mr120">
<span class="tip">车牌号</span>
<span class="text">辽A88888</span>
<span class="text">{{ carInfo.carCode }}</span>
</div>
<div class="car-group mr120">
<span class="tip">车位号</span>
<span class="text">E-666</span>
<span class="text">{{ carInfo.spaceNo }}</span>
</div>
<div class="car-group">
<span class="tip">停车时长</span>
<span class="text">1小时</span>
<span class="text">{{ carInfo.parkingTime }}</span>
</div>
</div>
<div class="go" @click="go">
@ -39,28 +39,50 @@
</template>
<script setup lang="ts">
defineProps({
import Message from '@/base/Message/Message'
import { useRootStore } from '@/store/root'
import { useRouter } from 'vue-router'
const store = useRootStore()
const router = useRouter()
const props = defineProps({
carInfo: {
type: Object,
default: () => ({})
}
})
const emits = defineEmits(['close', 'go'])
const emits = defineEmits(['close'])
function close() {
emits('close')
}
function go() {
emits('go')
const info = window.Map_QM.pathPark({ shopNum: props.carInfo.spaceNo })
if (info?.node?.length) {
const floor: any = store.buildingList[0].floorList.find(item => item.floorOrder === info.floor)?.floor
const shop = {
shopCode: '',
shopName: props.carInfo.spaceNo,
floorOrder: info.floor,
floor,
logoUrl: props.carInfo.carImage,
yaxis: info.node
}
store.SET_SHOP(shop)
router.push('/nav')
} else {
Message({ text: `暂未查到相关信息`, type: 'success' })
}
}
</script>
<style scoped>
<style lang="scss" scoped>
.car-info-wrapper {
position: fixed;
z-index: 20;
background: rgb(0 0 0 / 50%);
inset: 0;
.masker {
position: absolute;
inset: 0;

5
src/components/Carousel/Carousel.vue

@ -12,7 +12,7 @@
:dynamic-bullets="true"
class="myswiper"
>
<swiper-slide v-for="(item, index) in acList" :key="index">
<swiper-slide v-for="item in acList" :key="item.fileCode">
<img :src="item.fileUrl" class="img" />
</swiper-slide>
</swiper>
@ -25,8 +25,9 @@ import { Swiper, SwiperSlide } from 'swiper/vue'
import { Autoplay, Pagination } from 'swiper'
import 'swiper/css'
import 'swiper/css/pagination'
import type { Picture } from '@/types/activity'
type AcType = {
acList: any
acList: Picture[]
}
defineProps<AcType>()
const modules = ref([Autoplay, Pagination])

48
src/components/Menu/Menu.vue

@ -1,6 +1,12 @@
<template>
<div class="menu-container">
<div v-for="item in list" :key="item.title" class="menu-item" @click="changeMenu(item)">
<div
v-for="item in list"
:key="item.title"
:style="item.status === 1 ? 'display:none' : ''"
class="menu-item"
@click="changeMenu(item)"
>
<div class="top">
<img :src="current === item.path ? item.iconS : item.icon" alt="" />
<div v-if="current === item.path" class="ac"></div>
@ -11,79 +17,97 @@
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { ref, watch, toRefs } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStatisticsModel } from '@/composables/useStatistics'
import { useRootStore } from '@/store/root'
type MenuItem = {
title: string
titleEn: string
icon: string
iconS: string
path: string
status: 0 | 1 // 0 1
}
const list: MenuItem[] = [
const list = ref<MenuItem[]>([
{
title: '主页',
titleEn: 'Home',
icon: require('@/assets/images/menu/home.png'),
iconS: require('@/assets/images/menu/homes.png'),
path: '/'
path: '/',
status: 0
},
{
title: '店铺导航',
titleEn: 'Brand',
icon: require('@/assets/images/menu/brand.png'),
iconS: require('@/assets/images/menu/brands.png'),
path: '/brand'
path: '/brand',
status: 0
},
{
title: '优惠与活动',
titleEn: 'Activity',
icon: require('@/assets/images/menu/activity.png'),
iconS: require('@/assets/images/menu/activitys.png'),
path: '/activity'
path: '/activity',
status: 0
},
{
title: '会员专享',
titleEn: 'Member',
icon: require('@/assets/images/menu/member.png'),
iconS: require('@/assets/images/menu/members.png'),
path: '/member'
path: '/member',
status: 0
},
{
title: '服务',
titleEn: 'Service',
icon: require('@/assets/images/menu/service.png'),
iconS: require('@/assets/images/menu/services.png'),
path: '/service'
path: '/service',
status: 0
},
{
title: '停车与缴费',
titleEn: 'Parking',
icon: require('@/assets/images/menu/parking.png'),
iconS: require('@/assets/images/menu/parkings.png'),
path: '/parking'
path: '/parking',
status: 0
},
{
title: '文化学院',
titleEn: 'School',
icon: require('@/assets/images/menu/school.png'),
iconS: require('@/assets/images/menu/schools.png'),
path: '/school'
path: '/school',
status: 0
},
{
title: '艺术',
titleEn: 'Art',
icon: require('@/assets/images/menu/art.png'),
iconS: require('@/assets/images/menu/arts.png'),
path: '/art'
path: '/art',
status: 0
}
]
])
const store = useRootStore()
const { menuList } = toRefs(store)
const router = useRouter()
const route = useRoute()
const current = ref('/')
menuList.value.forEach((item, index) => {
list.value[index].status = item.status
})
function changeMenu(item: MenuItem) {
router.push(item.path)
useStatisticsModel({ recordType: 1, moduleName: item.title })
}
watch(route, to => {

26
src/components/PlateInput/PlateInput.vue

@ -17,7 +17,15 @@
</transition>
</div>
</TransitionGroup>
<div class="btn disabled" @click="confirm">
<div
class="btn"
:class="
((searchMethod === '车牌' && ((isEnergy && list.length === 8) || (!isEnergy && list.length === 7))) ||
(searchMethod === '车位' && list.length !== 0)) &&
'ac'
"
@click="confirm"
>
<slot></slot>
<span>查找车辆</span>
</div>
@ -51,7 +59,12 @@ function handleEnergy() {
})
}
function confirm() {
emits('confirm')
if (
(props.searchMethod === '车牌' && ((isEnergy.value && props.list.length === 8) || (!isEnergy.value && props.list.length === 7))) ||
(props.searchMethod === '车位' && props.list.length !== 0)
) {
emits('confirm')
}
}
onMounted(() => {
@ -91,7 +104,7 @@ $btn-width: 218px;
}
&.space-wrapper {
&::before {
left: 100px;
left: 95px;
}
}
.input-wrapper {
@ -119,7 +132,7 @@ $btn-width: 218px;
border: 2px solid #d4a866;
}
&.space {
width: 80px;
width: 75px;
margin-right: 10px;
&:nth-child(1) {
margin-right: 42px;
@ -158,9 +171,10 @@ $btn-width: 218px;
color: $btn-color;
background: $btn-bg;
border-radius: 12px;
opacity: 0.5;
box-shadow: 1px 16px 32px rgb(96 94 116 / 20%);
&.disabled {
opacity: 0.5;
&.ac {
opacity: 1;
}
span {
white-space: nowrap;

4
src/components/Search/Hot.vue

@ -11,7 +11,7 @@
<div class="name">{{ switchLanguage(item, 'shopName') }}</div>
<div class="right">
<img src="@/assets/images/search/position.png" alt="" />
<div class="hose_num">{{ item.houseNumber }}</div>
<div class="hose_num">{{ item.floor + '-' + item.houseNumber }}</div>
</div>
</div>
</div>
@ -24,6 +24,7 @@
import { ref } from 'vue'
import { getIndexJson } from '@/http/api/base'
import { useRootStore } from '@/store/root'
import { useStatistics } from '@/composables/useStatistics'
import ScrollView from '@/base/ScrollView/ScrollView.vue'
const list = ref<HotSearch[]>()
getIndexJson().then(({ data }) => {
@ -34,6 +35,7 @@ const store = useRootStore()
function show(item: any) {
store.SET_SHOP(item)
store.SET_SHOW_DETAIL(true)
useStatistics({ tag: 'brandSearch', shopCode: item.shopCode })
}
</script>

4
src/components/Search/Result.vue

@ -10,7 +10,7 @@
<div class="name">{{ switchLanguage(item, 'shopName') }}</div>
<div class="right">
<img src="@/assets/images/search/position.png" alt="" />
<div class="hose_num">{{ item.houseNumber }}</div>
<div class="hose_num">{{ item.floor + '-' + item.houseNumber }}</div>
</div>
</div>
</div>
@ -22,6 +22,7 @@
<script setup lang="ts">
import { useRootStore } from '@/store/root'
import { useStatistics } from '@/composables/useStatistics'
import ScrollView from '@/base/ScrollView/ScrollView.vue'
type ShopList = {
list: Shop[]
@ -31,6 +32,7 @@ const store = useRootStore()
function show(item: Shop) {
store.SET_SHOP(item)
store.SET_SHOW_DETAIL(true)
useStatistics({ tag: 'brandSearch', shopCode: item.shopCode })
}
</script>

2
src/components/ShopDetail/ShopDetail.vue

@ -97,7 +97,6 @@ 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'
@ -117,6 +116,7 @@ function close() {
}
//
function handleGo() {
useStatistics({ tag: 'navigation', shopCode: shop.value.shopCode })
store.SET_SHOW_DETAIL(false)
store.SET_SHOW_SEARCH(false)
router.push('/nav')

11
src/components/Traffic/Traffic.vue

@ -235,10 +235,13 @@ resList.forEach(item => {
item.sectionDesc === '东向西' ? changeStatus(item.status, roadList.value[0]) : changeStatus(item.status, roadList.value[1])
break
case '九龙街':
item.sectionDesc === '南向北' ? changeStatus(item.status, roadList.value[2]) : changeStatus(item.status, roadList.value[3])
break
case '博览路':
item.sectionDesc === '东向西' ? changeStatus(item.status, roadList.value[4]) : changeStatus(item.status, roadList.value[5])
if (item.sectionDesc === '南向北' || item.sectionDesc === '东向西') {
changeStatus(item.status, roadList.value[2])
changeStatus(item.status, roadList.value[4])
} else {
changeStatus(item.status, roadList.value[3])
changeStatus(item.status, roadList.value[5])
}
break
case '青年大街':
item.sectionDesc === '南向北' ? changeStatus(item.status, roadList.value[6]) : changeStatus(item.status, roadList.value[7])

27
src/composables/useActivityNav.ts

@ -1,27 +0,0 @@
import { useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { useRootStore } from '@/store/root'
import Brand from '@/utils/Class/Brand'
export const useActivityNav = () => {
const router = useRouter()
const store = useRootStore()
const { shopList } = storeToRefs(store)
function nav(activity: Activity) {
let shop
if (activity.shopCode.length) {
shop = shopList.value.find(item => item.shopCode === activity?.shopCode)
} else if (activity.point > -1) {
const { activityName, floorOrder, floor, point, fileUrl, activityId } = activity
shop = new Brand({ shopName: activityName, floorOrder, floor, logoUrl: fileUrl, yaxis: point, shopCode: activityId })
}
if (!shop) {
return
}
store.SET_SHOP(shop)
router.push('/nav')
}
return { nav }
}

4
src/composables/useFacilityNav.ts

@ -6,11 +6,11 @@ export const useFacilityNav = () => {
const store = useRootStore()
const router = useRouter()
function handleFacility({ abbreviation, customFacilityName, filePath, code }: Facility) {
function handleFacility({ abbreviation, customFacilityName, filePath, code, name }: Facility) {
const { floor, node } = window.Map_QM.pathIcon({ type: abbreviation })
const floorName = store.currentBuildingFloorsList.find(_floor => _floor.floorOrder === floor)?.floor
const shop = new Brand({
shopName: customFacilityName,
shopName: customFacilityName ? customFacilityName : name,
floorOrder: floor,
floor: floorName as string,
logoUrl: filePath,

72
src/composables/useFindCar.ts

@ -2,35 +2,69 @@ import { ref } from 'vue'
import { getFindCar } from '@/http/api/parking'
import { HTTP_CODE } from '@/enums'
import { isLicensePlate } from '@/utils/utils'
import { useRootStore } from '@/store/root'
import { useRouter } from 'vue-router'
import Message from '@/base/Message/Message'
export const useFindCar = () => {
const showCarDetail = ref(false)
const loading = ref(false)
const result = ref<CarInfo>()
async function confirm(plate: string) {
if (!isLicensePlate(plate)) {
Message({ text: '车牌错误,请重新输入', type: 'success' })
return
}
if (loading.value) {
return
}
try {
loading.value = true
const { code, msg, data } = await getFindCar(plate)
if (code === HTTP_CODE.ERR_OK) {
result.value = data
showCarDetail.value = true
const store = useRootStore()
const router = useRouter()
async function confirm(plate: string, type: number) {
if (!type) {
if (!isLicensePlate(plate)) {
Message({ text: '车牌错误,请重新输入', type: 'success' })
return
}
if (loading.value) {
return
}
try {
loading.value = true
const { code, msg, data } = await getFindCar(plate)
if (code === HTTP_CODE.ERR_OK) {
result.value = { ...data, carCode: plate, parkingTime: toHoursAndMinutes(Number(data.parkingTime)) }
showCarDetail.value = true
} else {
Message({ text: msg, type: 'success' })
}
} catch (error) {
Message({ text: error as string, type: 'success' })
} finally {
loading.value = false
}
} else {
if (!plate.length) {
Message({ type: 'success', text: '请输入正确的车位号' })
return
}
const info = window.Map_QM.pathPark({ shopNum: plate })
if (info?.node?.length) {
const floor: any = store.buildingList[0].floorList.find(item => item.floorOrder === info.floor)?.floor
const shop = {
shopCode: '',
shopName: plate,
floorOrder: info.floor,
floor,
logoUrl: '/static/img/tcjf.png',
yaxis: info.node
}
store.SET_SHOP(shop)
router.push('/nav')
} else {
Message({ text: msg, type: 'success' })
Message({ text: `暂未查到相关信息`, type: 'success' })
}
} catch (error) {
Message({ text: error as string, type: 'success' })
} finally {
loading.value = false
}
}
// 格式化停车时间
function toHoursAndMinutes(totalMinutes: number) {
const hours = Math.floor(totalMinutes / 60)
const minutes = totalMinutes % 60
return `${hours > 0 ? `${hours}小时` : ''}${minutes > 0 ? ` ${minutes}分钟` : ''}`
}
return { loading, result, showCarDetail, confirm }
}

3
src/composables/useHandleScreen.ts

@ -3,7 +3,7 @@ import { useRouter } from 'vue-router'
import { getBackTime } from '@/http/api/base'
import { useLogout } from '@/composables/useLogout'
import { isAndroid } from '@/utils/utils'
import { useStatistics } from '@/composables/useStatistics'
export const useHandleScreen = (callback: () => void) => {
const MIN_TIME = 0
const MAX_TIME = 5
@ -54,6 +54,7 @@ export const useHandleScreen = (callback: () => void) => {
}
async function checkHandleScreen(e: TouchEvent) {
useStatistics({ tag: 'device' })
!_isAndroid && addTotalClick(e)
toIndexTime.value = totalTime.value[0]
toWallpaperTime.value = totalTime.value[1]

25
src/composables/useInitConfigAndMallInfo.ts

@ -1,8 +1,9 @@
import { useRootStore } from '@/store/root'
import { getConfig, getFacilitiesList, getWeather } from '@/http/api/base'
import { getConfig, getFacilitiesList, getWeather, getArtList } from '@/http/api/base'
import { getShopAndBuildingList } from '@/http/api/shop'
import { getDeviceInfo } from '@/http/api/building'
import { getShopListByFloor, getShopListByIndustry, getBrandInfo } from '@/http/api/brand'
import { getModuleList } from '@/http/api/home'
import Message from '@/base/Message/Message'
export const useInitConfigAndMallInfo = async () => {
@ -11,14 +12,26 @@ export const useInitConfigAndMallInfo = async () => {
const store = useRootStore()
store.SET_CONFIG(_config.data)
const [_DeviceInfo, _shopAndBuilding, _facilityList, _weather, _shopListByFloor, _shopListByIndustry, _brandInfo] = await Promise.all([
const [
_DeviceInfo,
_shopAndBuilding,
_facilityList,
_weather,
_shopListByFloor,
_shopListByIndustry,
_brandInfo,
_menuList,
_pictureList
] = await Promise.all([
getDeviceInfo(),
getShopAndBuildingList(),
getFacilitiesList(),
getWeather(),
getShopListByFloor(),
getShopListByIndustry(),
getBrandInfo()
getBrandInfo(),
getModuleList(),
getArtList()
])
const { shopList, buildingList } = _shopAndBuilding.data
@ -30,6 +43,12 @@ export const useInitConfigAndMallInfo = async () => {
store.SET_SHOP_LIST_BY_INDUSTRY(_shopListByIndustry.data.list)
store.SET_FACILITY_LIST(_facilityList.data)
store.SET_WEATHER(_weather.data)
_menuList.data.unshift({
moduleName: '主页',
status: 0
})
store.SET_MENU_LIST(_menuList.data)
store.SET_PICTURE_LIST(_pictureList.data)
} catch (error) {
Message({ text: '初始化数据失败', type: 'success' })
}

4
src/composables/useParkingKeyboard.ts

@ -6,8 +6,8 @@ type SearchMethods = '车牌' | '车位'
export const useParkingKeyboard = () => {
const NOT_ENERGY_PLATE = 7 //非能源车牌长度
const ENERGY_PLATE = 8 //能源车牌长度
const SPACE_MAX_LENGTH = 4 //车位最大允许长度
const LICENSE = ['', 'A'] //默认车牌前缀
const SPACE_MAX_LENGTH = 7 //车位最大允许长度
const LICENSE = ['', 'A'] //默认车牌前缀
const plate = ref(LICENSE.slice())
const plateToString = computed(() => plate.value.join(''))

37
src/composables/useStatistics.ts

@ -1,16 +1,24 @@
import { useRootStore } from '@/store/root'
import { storeToRefs } from 'pinia'
import { getStatistics } from '@/http/api/statistics'
import type { Query, TagType } from '@/http/api/statistics/types'
import { getStatistics, getGuideClickDataUpload } from '@/http/api/statistics'
import type { Query, TagType, Clickquery, RecordType } from '@/http/api/statistics/types'
//店铺编码: tag=navigation或shop或brandSearch或时必传
//industryCode : tag=industry时必传
export const useStatistics = ({ tag, shopCode, industryCode = '' }: { tag: TagType; shopCode: string | number; industryCode?: string }) => {
export const useStatistics = ({
tag,
shopCode,
industryCode = ''
}: {
tag: TagType
shopCode?: string | number
industryCode?: string
}) => {
const store = useRootStore()
const { device } = storeToRefs(store)
const params: Query = {
deviceCode: device.value.deviceCode,
deviceCode: device.value.machineCode,
projectCode: device.value.projectCode,
tag,
shopCode,
@ -19,3 +27,24 @@ export const useStatistics = ({ tag, shopCode, industryCode = '' }: { tag: TagTy
getStatistics(params)
}
type Stype = {
recordType: RecordType
moduleName?: string
activityCode?: string
}
// 模块、活动、使用人次统计
export const useStatisticsModel = ({ recordType, moduleName, activityCode }: Stype) => {
const store = useRootStore()
const { device } = storeToRefs(store)
const params: Clickquery = {
deviceCode: device.value.machineCode,
projectCode: device.value.projectCode,
recordType,
moduleName,
activityCode
}
getGuideClickDataUpload(params)
}

12
src/enums/index.ts

@ -25,3 +25,15 @@ export enum HTTP_CODE {
ERR_NULL = 401, //未识别到语音
ERR_DISCERNING = 201 //语音识别中
}
export enum PictureStatus {
SCHOOL = 1, // 文化学院
GOLD = 2, // 金卡会员
BLACK = 3, // 黑卡会员
ACTIVITY = 4 // 活动
}
export enum PictureType {
H = 1, // 横版图片
V = 2 // 竖版图片
}

10
src/http/api/activity/index.ts

@ -1,10 +0,0 @@
import { request } from '@/http/http'
type AcType = {
activityList: Activity[]
}
//获取商场活动
export const getMallActivity = () => request<AcType>({ url: `/JSON/getActivityList1.json` })
//获取店铺活动
export const getShopActivity = () => request({ url: `/JSON/getActivityList2.json` })

4
src/http/api/base/index.ts

@ -1,4 +1,5 @@
import { request } from '@/http/http'
import type { Picture } from '@/types/activity'
import type { WrittenQuery } from './types'
//获取配置项
@ -21,3 +22,6 @@ export const getHandWriting = (data: WrittenQuery) => request<string[]>({ url: '
// 获取首页数据
export const getIndexJson = () => request({ url: `/JSON/index.json` })
// 获取活动、会员卡等
export const getArtList = () => request<Picture[]>({ url: `/JSON/getArtList.json` })

4
src/http/api/home/index.ts

@ -0,0 +1,4 @@
import { request } from '../../http'
//获取菜单开关
export const getModuleList = () => request<MenuType[]>({ url: `/JSON/getModuleList.json` })

3
src/http/api/member/index.ts

@ -1,3 +0,0 @@
import { request } from '../../http'
// 获取会员信息
export const getMemberInfo = () => request<MemberInfo>({ url: `/JSON/getMemberInterests.json` })

5
src/http/api/statistics/index.ts

@ -1,4 +1,7 @@
import { request } from '../../http'
import type { Query } from './types'
import type { Query, Clickquery } from './types'
//数据统计
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' })

9
src/http/api/statistics/types.ts

@ -1,5 +1,6 @@
//类型,设备点击量:device,导航使用次数:navigation,节目播放次数:program,店铺点击次数:shop,业态点击次数:industry,品牌店铺搜索:brandSearch
export type TagType = 'navigation' | 'shop' | 'brandSearch' | 'device' | 'program' | 'industry'
export type RecordType = 1 | 2 | 3 // 记录类型1:模块点击记录 2:活动点击记录 3:使用人次记录
export type Query = {
deviceCode: string //设备编码
@ -8,3 +9,11 @@ export type Query = {
shopCode?: string | number
industryCode?: string //tag=industry时必传
}
export type Clickquery = {
deviceCode: string //设备编码
projectCode: string //项目编码
recordType: RecordType
moduleName?: string // 模块名称
activityCode?: string // 活动code
}

9
src/store/root/actions.ts

@ -3,6 +3,7 @@ import type { State } from './state'
import type { Root } from '../key'
import type { CreateActions } from '../types'
import { BrandRes, GroupList } from '@/http/api/brand/types'
import { Picture } from '@/types/activity'
export interface Actions {
SET_SHOP_LIST_BY_INDUSTRY(list: GroupList): void
@ -19,6 +20,8 @@ export interface Actions {
SET_MAP_STATUS(flag: boolean): void
SET_SHOW_DETAIL(flag: boolean): void
SET_SHOW_SEARCH(flag: boolean): void
SET_MENU_LIST(list: MenuType[]): void
SET_PICTURE_LIST(list: Picture[]): void
}
export type GenActions = CreateActions<Root, State, Actions>
@ -68,5 +71,11 @@ export const actions: GenActions = {
},
SET_MAP_STATUS(flag) {
this.mapStatus = flag
},
SET_MENU_LIST(list) {
this.menuList = list
},
SET_PICTURE_LIST(list) {
this.pictureList = list
}
}

7
src/store/root/state.ts

@ -1,4 +1,5 @@
import type { GroupList, BrandRes } from '@/http/api/brand/types'
import { Picture } from '@/types/activity'
export interface State {
shopList: Readonly<Shop[]> //店铺列表
@ -15,6 +16,8 @@ export interface State {
mapStatus: boolean //地图加载是否成功
device: Device //当前设备信息
shop: Shop //店铺信息
menuList: MenuType[] // 菜单信息
pictureList: Picture[] // 图片列表
}
export const state = (): State => ({
@ -31,5 +34,7 @@ export const state = (): State => ({
config: {} as Config,
mapStatus: false,
device: {} as Device,
shop: {} as Shop
shop: {} as Shop,
menuList: [],
pictureList: []
})

8
src/types/activity.d.ts

@ -1,3 +1,4 @@
import { PictureStatus, PictureType } from '@/enums'
declare interface Activity {
activityAddress: string //活动地址
activityAddressEn: string //活动地址英文
@ -20,3 +21,10 @@ declare interface Activity {
point: number // 导航点
shopCode: string //关联店铺code
}
declare interface Picture {
fileCode: string // 图片编码
fileUrl: string // 图片地址
flag: PictureType // 图片横竖
artType: PictureStatus // 图片类型
}

4
src/types/car.d.ts

@ -6,6 +6,6 @@ declare interface CarInfo {
cost: number //费用
enterTime: string //入场时间
floor: string //楼层
parkingTime: number // 停车时长
placeCode: string //车位号
parkingTime: string // 停车时长
spaceNo: string //车位号
}

2
src/types/map.d.ts

@ -288,7 +288,7 @@ export declare global {
*/
pathPark(obj: { shopNum: string }): {
shopNum: string
node: string | number
node: string
floor: number
xaxis: number | string
yaxis: number | string

4
src/types/menu.d.ts

@ -0,0 +1,4 @@
declare interface MenuType {
moduleName: string // 模块名称
status: 1 | 0 // 0 正常 1 关闭
}

16
src/views/Activity/Activity.vue

@ -8,12 +8,18 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getMallActivity } from '@/http/api/activity'
import { ref, toRefs } from 'vue'
import type { Picture } from '@/types/activity'
import { useRootStore } from '@/store/root'
import { PictureStatus, PictureType } from '@/enums'
import Carousel from '@/components/Carousel/Carousel.vue'
const aclist = ref<Activity[]>([])
getMallActivity().then(({ data }) => {
aclist.value = data.activityList
const aclist = ref<Picture[]>([])
const store = useRootStore()
const { pictureList } = toRefs(store)
pictureList.value.forEach(item => {
if (item.artType === PictureStatus.ACTIVITY && item.flag === PictureType.H) {
aclist.value.push(item)
}
})
</script>

3
src/views/Brand/Brand.vue

@ -48,7 +48,7 @@ import { ref, computed, shallowRef } from 'vue'
import { storeToRefs } from 'pinia'
import { useRootStore } from '@/store/root'
import { useStatistics } from '@/composables/useStatistics'
const store = useRootStore()
const { shopList, device } = storeToRefs(store)
@ -164,6 +164,7 @@ function handleClickFormat(item: Industry, index: number) {
}
if (currentTypeId.value === 0) {
copyShopList.value = shopList.value.filter(shop => shop.industryFatherCode === item.industryCode)
useStatistics({ tag: 'industry', industryCode: item.industryCode })
} else {
copyShopList.value = shopList.value.filter(shop => shop.initials?.charAt(0) === item.industryName)
}

37
src/views/Index/Middle.vue

@ -1,26 +1,26 @@
<template>
<Transition name="zoom">
<div class="middle-container">
<div class="brand" @click="go('brand')">
<div class="brand" @click="go('brand', '店铺导航')">
<div class="txt_w">{{ switchLanguage(list[0], 'title') }}</div>
<div class="sear">{{ $t('searB') }}</div>
</div>
<div class="activity" @click="go('activity')">
<div class="activity" @click="go('activity', '优惠与活动')">
<div class="txt">{{ switchLanguage(list[1], 'title') }}</div>
</div>
<div class="art" @click="go('art')">
<div class="art" @click="go('art', '艺术')">
<div class="txt_w">{{ switchLanguage(list[6], 'title') }}</div>
</div>
<div class="school" @click="go('school')">
<div class="school" @click="go('school', '文化学院')">
<div class="txt_w">{{ switchLanguage(list[5], 'title') }}</div>
</div>
<div class="service" @click="go('service')">
<div class="service" @click="go('service', '服务')">
<div class="txt_w">{{ switchLanguage(list[3], 'title') }}</div>
</div>
<div class="member" @click="go('member')">
<div class="member" @click="go('member', '会员专享')">
<div class="txt_w">{{ switchLanguage(list[2], 'title') }}</div>
</div>
<div class="parking" @click="go('parking')">
<div class="parking" @click="go('parking', '停车与缴费')">
<div class="txt">{{ switchLanguage(list[4], 'title') }}</div>
</div>
</div>
@ -29,6 +29,10 @@
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { toRefs } from 'vue'
import { useStatisticsModel } from '@/composables/useStatistics'
import { useRootStore } from '@/store/root'
import Message from '@/base/Message/Message'
const list = [
{
title: '店铺导航',
@ -60,8 +64,23 @@ const list = [
}
]
const router = useRouter()
function go(path: string) {
router.push(path)
const store = useRootStore()
const { menuList } = toRefs(store)
function go(path: string, moduleName: string) {
let isGo = true
for (const menu of menuList.value) {
if (menu.moduleName === moduleName) {
menu.status === 1 && (isGo = false)
break
}
}
//
if (isGo) {
router.push(path)
useStatisticsModel({ recordType: 1, moduleName })
} else {
Message({ text: '敬请期待', type: 'success' })
}
}
</script>

49
src/views/Member/Member.vue

@ -1,15 +1,20 @@
<template>
<typeBtnGroup class="top" :list="list" />
<transition appear enter-active-class="animate__animated animate__fadeIn" leave-active-class="animate__animated animate__zoomOut">
<div class="carousel">
<Carousel :ac-list="memberInfo" />
<typeBtnGroup class="top" :list="list" @change-type="change" />
<transition appear enter-active-class="animate__animated animate__fadeIn">
<div v-if="current === 0" class="carousel">
<Carousel :ac-list="goldMemberInfo" />
</div>
<div v-else class="carousel">
<Carousel :ac-list="blackMemberInfo" />
</div>
</transition>
</template>
<script setup lang="ts">
import { shallowRef } from 'vue'
import { getMemberInfo } from '@/http/api/member/index'
import { ref, shallowRef, toRefs } from 'vue'
import type { Picture } from '@/types/activity'
import { useRootStore } from '@/store/root'
import { PictureStatus, PictureType } from '@/enums'
import Carousel from '@/components/Carousel/Carousel.vue'
import typeBtnGroup from '@/components/TypeBtnList/TypeBtnList.vue'
const list = [
@ -22,16 +27,34 @@ const list = [
titleEn: 'Black Card Member'
}
]
const memberInfo = shallowRef<fileList[]>([])
getMemberInfo().then(({ data }) => {
if (data.fileList) {
memberInfo.value = data.fileList?.map(item => {
return {
fileUrl: item
const store = useRootStore()
const { pictureList } = toRefs(store)
const goldMemberInfo = shallowRef<Picture[]>([])
const blackMemberInfo = shallowRef<Picture[]>([])
const current = ref(0)
function getInfo(status: PictureStatus) {
if (status === PictureStatus.GOLD) {
goldMemberInfo.value = []
pictureList.value.forEach(item => {
if (item.artType === status && item.flag === PictureType.H) {
goldMemberInfo.value.push(item)
}
})
} else {
blackMemberInfo.value = []
pictureList.value.forEach(item => {
if (item.artType === status && item.flag === PictureType.H) {
blackMemberInfo.value.push(item)
}
})
}
})
}
getInfo(PictureStatus.GOLD)
function change(params: any) {
current.value = params.order
params.order === 0 ? getInfo(PictureStatus.GOLD) : getInfo(PictureStatus.BLACK)
}
</script>
<style lang="scss" scoped>

3
src/views/Nav/Nav.vue

@ -162,7 +162,6 @@ import { useMapNavControl } from '@/composables/useMapNavControl'
import { useChangeNavMethod } from '@/composables/useChangeNavMethod'
import { useStartNavi } from '@/composables/useStartNavi'
import { useSetCameraViews } from '@/composables/useSetCameraViews'
import { useStatistics } from '@/composables/useStatistics'
import { hideMapDialog } from '@/composables/useInitMap'
import { i18n } from '@/i18n'
import { useRouter, useRoute } from 'vue-router'
@ -174,8 +173,6 @@ import ScrollView from '@/base/ScrollView/ScrollView.vue'
const store = useRootStore()
const { shop, device, language, config } = storeToRefs(store)
useStatistics({ tag: 'navigation', shopCode: shop.value.shopCode })
const { replay, pause, speedUp, handleReplay, togglePause, handleSpeedUp, resetPause } = useMapNavControl()
const { directionInfo, pathShopList, backPathArray, startNavi } = useStartNavi(shop, device, resetPause)
const { methodIdx, methodsList, handleControl } = useChangeNavMethod(backPathArray)

15
src/views/Parking/Parking.vue

@ -21,17 +21,19 @@
</div>
<div class="content-right">
<div class="parking-carousel">
<EffectFade></EffectFade>
<EffectFade v-slot="{ item }" :list="parkingInfo.fileList">
<img class="img" :src="item" alt="" />
</EffectFade>
</div>
<h1 class="title">{{ switchLanguage(parkingInfo, 'title') }}</h1>
<ScrollView class="parking-scroll" scrollbar :list="switchLanguage(parkingInfo, 'content')">
<ScrollView class="parking-scroll" scrollbar :list="switchLanguage(parkingInfo, 'content')" :pull-up="false">
<div class="intro">{{ switchLanguage(parkingInfo, 'content') }}</div>
</ScrollView>
</div>
</div>
<Traffic v-else />
</div>
<CarInfo v-if="showCarDetail" @close="showCarDetail = false" @go="onConfirm" />
<CarInfo v-if="showCarDetail" :car-info="result" @close="showCarDetail = false" />
</template>
<script setup lang="ts">
@ -79,7 +81,7 @@ const { confirm, loading, showCarDetail, result } = useFindCar()
function onConfirm() {
plate.value = LICENSE
confirm(plateToString.value)
confirm(plateToString.value, tabIdx.value)
}
const parkingInfo = shallowRef<ParkingInfo>({} as ParkingInfo)
@ -158,6 +160,11 @@ getParkingInfo().then(({ data }) => {
:deep(.stay-tuned) {
height: 200px;
}
.img {
width: 540px;
height: 304px;
border-radius: 8px 8px 0 0;
}
}
.title {
margin: 0 48px 12px;

16
src/views/School/School.vue

@ -8,12 +8,18 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getMallActivity } from '@/http/api/activity'
import { ref, toRefs } from 'vue'
import type { Picture } from '@/types/activity'
import { useRootStore } from '@/store/root'
import { PictureStatus, PictureType } from '@/enums'
import Carousel from '@/components/Carousel/Carousel.vue'
const aclist = ref<Activity[]>([])
getMallActivity().then(({ data }) => {
aclist.value = data.activityList
const aclist = ref<Picture[]>([])
const store = useRootStore()
const { pictureList } = toRefs(store)
pictureList.value.forEach(item => {
if (item.artType === PictureStatus.SCHOOL && item.flag === PictureType.H) {
aclist.value.push(item)
}
})
</script>

Loading…
Cancel
Save