From d275da4dd108d253beef00869ef3308bf446e72f Mon Sep 17 00:00:00 2001 From: jiangx <1457960500@qq.com> Date: Mon, 27 Mar 2023 15:19:51 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=9A=80=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=88=86=E9=A1=B5hooks=E4=BB=A5=E5=8F=8A=E5=88=86=E9=A1=B5?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E6=94=BE=E5=9C=A8worker=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/static/worker/page.worker.js | 82 +++++++++++++++++++++++++++ src/assets/images/nav/2D.svg | 3 + src/assets/images/nav/3D.svg | 3 + src/assets/images/nav/big_down.svg | 5 ++ src/assets/images/nav/big_left.svg | 5 ++ src/assets/images/nav/big_right.svg | 5 ++ src/assets/images/nav/big_up.svg | 5 ++ src/assets/images/nav/down_thumb.svg | 3 + src/assets/images/nav/ft.svg | 3 + src/assets/images/nav/left_thumb.svg | 3 + src/assets/images/nav/path.svg | 3 + src/assets/images/nav/right_thumb.svg | 3 + src/assets/images/nav/up_thumb.svg | 3 + src/assets/images/nav/zt.svg | 3 + src/base/ScrollView/ScrollView.vue | 17 +++++- src/composables/useActivityNav.ts | 4 +- src/composables/useChangeNavMethod.ts | 8 +-- src/composables/useFacilityNav.ts | 11 ++-- src/composables/usePage.ts | 46 +++++++++++++++ src/composables/useSearchShop.ts | 4 +- src/composables/useStatistics.ts | 2 +- src/http/api/statistics/types.ts | 2 +- src/types/map.d.ts | 6 +- src/types/shop.d.ts | 40 ++++++------- src/utils/Class/Brand.ts | 6 +- src/views/Guide/Guide.vue | 10 +--- src/views/Nav/Nav.vue | 28 ++++----- 27 files changed, 248 insertions(+), 65 deletions(-) create mode 100644 public/static/worker/page.worker.js create mode 100644 src/assets/images/nav/2D.svg create mode 100644 src/assets/images/nav/3D.svg create mode 100644 src/assets/images/nav/big_down.svg create mode 100644 src/assets/images/nav/big_left.svg create mode 100644 src/assets/images/nav/big_right.svg create mode 100644 src/assets/images/nav/big_up.svg create mode 100644 src/assets/images/nav/down_thumb.svg create mode 100644 src/assets/images/nav/ft.svg create mode 100644 src/assets/images/nav/left_thumb.svg create mode 100644 src/assets/images/nav/path.svg create mode 100644 src/assets/images/nav/right_thumb.svg create mode 100644 src/assets/images/nav/up_thumb.svg create mode 100644 src/assets/images/nav/zt.svg create mode 100644 src/composables/usePage.ts diff --git a/public/static/worker/page.worker.js b/public/static/worker/page.worker.js new file mode 100644 index 0000000..82ca623 --- /dev/null +++ b/public/static/worker/page.worker.js @@ -0,0 +1,82 @@ +const MAX_LENGTH = 20 +let pageIndex = 1 //数组中需要分页(即下标为pageIdx的数据)的当前页 大数组中的二维 +const pageSize = 20 //一页显示的条数 +let pageList = [] //用于UI渲染的列表 +let showMore = false +let pageIdx = 0 //当前是数组中的哪一项需要分页 大数组中的一维 +let allList = [] +let loaded = false +function loadMore(_pageIndex) { + if (!Array.isArray(allList)) { + return + } + //如果数组中的大分页项大于等于大数组的长度则全部分页完成 + if (pageIdx >= allList.length) { + loaded = true + return + } + pageIndex = _pageIndex + const size = allList[pageIdx].shopList.slice(0, pageIndex * pageSize) + //数组中需要分页的列表项是否存在于渲染列表中 如果有则直接把分页的数据赋值 没有则新开一个放到渲染列表中 + if (pageList[pageIdx]?.name) { + pageList[pageIdx].shopList = size + } else { + pageList.push({ + name: allList[pageIdx].name, + shopList: size + }) + } + + showMore = false +} + + function scrollEnd() { + if (pageIdx >= allList.length || pageIdx < 0) { + loaded = true + return + } + if (pageList[pageIdx].shopList.length >= allList[pageIdx].shopList.length) { + pageIdx++ + pageIndex = 1 + loadMore(pageIndex) + return + } + if (!showMore) { + showMore = true + loadMore(pageIndex + 1) + } + } + + self.onmessage = e => { + if (Array.isArray(e.data)) { + allList = e.data + } + if (e.data === 'scrollEnd') { + scrollEnd(allList) + self.postMessage({ pageList, loaded, refresh: false }) + return + } + //数据变化时重置分页数据 一般是点击了业态或楼层筛选 + loaded = false + pageIndex = 1 + pageList = [] + + //找出数据中店铺列表长度大于分页点的索引 从索引处开始分页 + pageIdx = allList.findIndex(item => item.shopList.length > MAX_LENGTH) + + //pageIdx小于0的话 说明没有店铺列表长度大于分页点的 无需分页直接返回数据 + if (pageIdx < 0) { + pageList = e.data + loaded = true + self.postMessage({ pageList, loaded, refresh: true }) + return + } + if (pageIdx !== 0) { + for (let i = 0; i < pageIdx; i++) { + pageList.push(allList[i]) + } + } + loadMore(pageIndex, allList) + self.postMessage({ pageList, loaded, refresh: true }) + } + diff --git a/src/assets/images/nav/2D.svg b/src/assets/images/nav/2D.svg new file mode 100644 index 0000000..db6e59b --- /dev/null +++ b/src/assets/images/nav/2D.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/3D.svg b/src/assets/images/nav/3D.svg new file mode 100644 index 0000000..286f6e2 --- /dev/null +++ b/src/assets/images/nav/3D.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/big_down.svg b/src/assets/images/nav/big_down.svg new file mode 100644 index 0000000..0690868 --- /dev/null +++ b/src/assets/images/nav/big_down.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/nav/big_left.svg b/src/assets/images/nav/big_left.svg new file mode 100644 index 0000000..91de5fd --- /dev/null +++ b/src/assets/images/nav/big_left.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/nav/big_right.svg b/src/assets/images/nav/big_right.svg new file mode 100644 index 0000000..598149f --- /dev/null +++ b/src/assets/images/nav/big_right.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/nav/big_up.svg b/src/assets/images/nav/big_up.svg new file mode 100644 index 0000000..d55b9ed --- /dev/null +++ b/src/assets/images/nav/big_up.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/nav/down_thumb.svg b/src/assets/images/nav/down_thumb.svg new file mode 100644 index 0000000..731e13c --- /dev/null +++ b/src/assets/images/nav/down_thumb.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/ft.svg b/src/assets/images/nav/ft.svg new file mode 100644 index 0000000..699d30d --- /dev/null +++ b/src/assets/images/nav/ft.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/left_thumb.svg b/src/assets/images/nav/left_thumb.svg new file mode 100644 index 0000000..fc34f62 --- /dev/null +++ b/src/assets/images/nav/left_thumb.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/path.svg b/src/assets/images/nav/path.svg new file mode 100644 index 0000000..2fe051a --- /dev/null +++ b/src/assets/images/nav/path.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/right_thumb.svg b/src/assets/images/nav/right_thumb.svg new file mode 100644 index 0000000..9eca66c --- /dev/null +++ b/src/assets/images/nav/right_thumb.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/up_thumb.svg b/src/assets/images/nav/up_thumb.svg new file mode 100644 index 0000000..77d52ec --- /dev/null +++ b/src/assets/images/nav/up_thumb.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/nav/zt.svg b/src/assets/images/nav/zt.svg new file mode 100644 index 0000000..a3b487a --- /dev/null +++ b/src/assets/images/nav/zt.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/base/ScrollView/ScrollView.vue b/src/base/ScrollView/ScrollView.vue index 9bc0b5a..a979fd2 100644 --- a/src/base/ScrollView/ScrollView.vue +++ b/src/base/ScrollView/ScrollView.vue @@ -26,6 +26,7 @@ type Props = { refreshDelay?: number scrollTop?: boolean stopPropagation?: boolean + pullUp: boolean } const props = withDefaults(defineProps(), { @@ -37,7 +38,8 @@ const props = withDefaults(defineProps(), { deceleration: 0.02, refreshDelay: 20, scrollTop: true, - stopPropagation: false + stopPropagation: false, + pullUp: false }) const _BScrollRef = shallowRef(null) @@ -46,6 +48,8 @@ const timer = ref() const store = useStore() const { language } = toRefs(store) +const emits = defineEmits(['scroll-end']) + function _initScroll() { if (!scrollDOMRef.value) { return @@ -61,6 +65,17 @@ function _initScroll() { observeImage: props.observeImage, stopPropagation: props.stopPropagation }) + + if (props.pullUp) { + _BScrollRef.value.on('scrollEnd', () => { + if (!_BScrollRef.value) { + return + } + if (_BScrollRef.value?.y <= _BScrollRef.value?.maxScrollY + 50) { + emits('scroll-end') + } + }) + } } function refresh() { diff --git a/src/composables/useActivityNav.ts b/src/composables/useActivityNav.ts index 4ba0907..ecf0790 100644 --- a/src/composables/useActivityNav.ts +++ b/src/composables/useActivityNav.ts @@ -13,8 +13,8 @@ export const useActivityNav = () => { if (activity?.shopCode?.length) { shop = shopList.value.find(item => item.shopCode === activity?.shopCode) } else if (typeof activity.point === 'number') { - const { activityName, floorOrder, floor, point, fileUrl } = activity - shop = new Brand({ shopName: activityName, floorOrder, floor, logoUrl: fileUrl, yaxis: point }) + const { activityName, floorOrder, floor, point, fileUrl, activityId } = activity + shop = new Brand({ shopName: activityName, floorOrder, floor, logoUrl: fileUrl, yaxis: point, shopCode: activityId }) } if (!shop) { return diff --git a/src/composables/useChangeNavMethod.ts b/src/composables/useChangeNavMethod.ts index 504f807..1afbe46 100644 --- a/src/composables/useChangeNavMethod.ts +++ b/src/composables/useChangeNavMethod.ts @@ -5,14 +5,8 @@ import { NavMethods, methodsList } from '@/views/Nav/methodsList' * * * @param {Function} callback - * @return { - * methodsList: 导航路线 最佳 扶梯 电梯; - * methodIdx: 当前路线选中的索引; - * handleControl: 切换路线 此函数一般绑定于视图层; - * selectedWayMethods: 选中哪条路线; - * } */ -export const useChangeNavMethod = (callback: () => void) => { +export const useChangeNavMethod = (callback: ({ direction, wayList }: { direction: Direction; wayList: Shop[] }) => void) => { const methodIdx = ref(0) //切换导航路线 function handleControl(method: NavMethods, index: number) { diff --git a/src/composables/useFacilityNav.ts b/src/composables/useFacilityNav.ts index 24851cb..bc2536f 100644 --- a/src/composables/useFacilityNav.ts +++ b/src/composables/useFacilityNav.ts @@ -6,15 +6,16 @@ export const useFacilityNav = () => { const store = useStore() const router = useRouter() - function handleFacility(item: Facility) { - const facility = window.Map_QM.pathIcon({ type: item.abbreviation }) + function handleFacility({ abbreviation, customFacilityName, filePath, code }: Facility) { + const facility = window.Map_QM.pathIcon({ type: abbreviation }) const floorName = store.currentBuildingFloorsList.find(floor => floor.floorOrder === facility.floor)?.floor const shop = new Brand({ - shopName: item.customFacilityName, + shopName: customFacilityName, floorOrder: facility.floor, floor: floorName as string, - logoUrl: item.filePath, - yaxis: facility.node + logoUrl: filePath, + yaxis: facility.node, + shopCode: code }) store.SET_SHOP(shop) router.push('/nav') diff --git a/src/composables/usePage.ts b/src/composables/usePage.ts new file mode 100644 index 0000000..45d4656 --- /dev/null +++ b/src/composables/usePage.ts @@ -0,0 +1,46 @@ +import { ref, shallowRef, watch, toRaw, nextTick, onBeforeUnmount, type ShallowRef } from 'vue' + +/** + * @param {array} totalList 分页数据源 + * @param {*} scroll 滚动组件的实例 + * @return {*} { scrollEnd, pageList, loaded } + */ +type PageList = { name: string; shopList: Shop[] } +export const usePage = (totalList: PageList[], scroll: ShallowRef) => { + if (typeof Worker === 'undefined') { + alert('抱歉,当前运行环境不支持Web Worker API, 请升级浏览器版本') + } + const pageList = shallowRef([]) //用于UI渲染的列表 + const loaded = ref(false) + const worker = ref() + worker.value = new Worker('./static/worker/page.worker.js') + worker.value.onmessage = e => { + pageList.value = e.data.pageList + loaded.value = e.data.loaded + if (e.data.refresh) { + nextTick(() => { + scroll.value?.scrollTo?.(0, 0, 100) + }) + } + } + + function scrollEnd() { + worker.value?.postMessage('scrollEnd') + } + watch( + totalList, + newVal => { + const rawList = newVal.map(item => toRaw(item)) + worker.value?.postMessage(rawList) + }, + { + immediate: true + } + ) + + onBeforeUnmount(() => { + worker.value?.terminate() + }) + + return { scrollEnd, pageList, loaded } +} diff --git a/src/composables/useSearchShop.ts b/src/composables/useSearchShop.ts index 623f1ec..72cbfd7 100644 --- a/src/composables/useSearchShop.ts +++ b/src/composables/useSearchShop.ts @@ -1,6 +1,6 @@ import { computed, shallowRef, watch } from 'vue' import { useStore } from '@/store/root' -import type { Ref } from 'vue' +import type { Ref, ShallowRef } from 'vue' /** *` * @@ -8,7 +8,7 @@ import type { Ref } from 'vue' * @param {Ref>} [searchType=0] 0:键盘搜索 1:手写搜索 * @return {*} [searchShopListRef] */ -export const useSearchShop = (watchName: Ref, searchType: Ref<0 | 1>): { searchShopListRef: Ref } => { +export const useSearchShop = (watchName: Ref, searchType: Ref<0 | 1>): { searchShopListRef: ShallowRef } => { const store = useStore() const searchShopListRef = shallowRef([]) const cacheFirstSearchListRef = shallowRef([]) //缓存第一次检索首字母后的列表结果 diff --git a/src/composables/useStatistics.ts b/src/composables/useStatistics.ts index b6d7be7..2ff9bd4 100644 --- a/src/composables/useStatistics.ts +++ b/src/composables/useStatistics.ts @@ -5,7 +5,7 @@ import type { Query, TagType } from '@/http/api/statistics/types' //店铺编码: tag=navigation或shop或brandSearch或时必传 //industryCode : tag=industry时必传 -export const useStatistics = ({ tag, shopCode, industryCode }: { tag: TagType; shopCode: string; industryCode: string }) => { +export const useStatistics = ({ tag, shopCode, industryCode = '' }: { tag: TagType; shopCode: string | number; industryCode?: string }) => { const store = useStore() const { currentFloor } = storeToRefs(store) diff --git a/src/http/api/statistics/types.ts b/src/http/api/statistics/types.ts index 9723874..87efa22 100644 --- a/src/http/api/statistics/types.ts +++ b/src/http/api/statistics/types.ts @@ -5,6 +5,6 @@ export type Query = { deviceCode: string //设备编码 projectCode: string //项目编码 tag: TagType - shopCode?: string + shopCode?: string | number industryCode?: string //tag=industry时必传 } diff --git a/src/types/map.d.ts b/src/types/map.d.ts index 10c5c36..4229d53 100644 --- a/src/types/map.d.ts +++ b/src/types/map.d.ts @@ -169,19 +169,19 @@ export declare global { * 导航切换扶梯模式 * @param callBack 回调函数 */ - ChangePathByFt(callBack?: () => void): void + ChangePathByFt(callBack?: ({ direction, wayList }: { direction: Direction; wayList: Shop[] }) => void): void /** * 导航切换最佳模式 * @param callBack 回调函数 */ - ChangePathByGood(callBack?: () => void): void + ChangePathByGood(callBack?: ({ direction, wayList }: { direction: Direction; wayList: Shop[] }) => void): void /** * 导航切换电梯模式 * @param callBack 回调函数 */ - ChangePathByDt(callBack?: () => void): void + ChangePathByDt(callBack?: ({ direction, wayList }: { direction: Direction; wayList: Shop[] }) => void): void /** * 地图图标弹跳效果 diff --git a/src/types/shop.d.ts b/src/types/shop.d.ts index 1b96bbe..ea4f95b 100644 --- a/src/types/shop.d.ts +++ b/src/types/shop.d.ts @@ -1,25 +1,25 @@ declare interface Shop { - shopName: string - floor: string - floorOrder: number - logoUrl: string - yaxis: number | string - shopCode?: string - shopNameEn?: string - initials?: string - spelling?: string + shopName: string //店铺名 + floor: string //所属楼层名称 从 0 开始递增 + floorOrder: number //楼层编号 + logoUrl: string //logo图片 + yaxis: number | string //店铺导航点 + shopCode: string | number //店铺code + shopNameEn?: string //店铺英文名 + initials?: string //店铺名首字母 + spelling?: string //店铺名称中文全拼 alias?: string //店铺别名 - borderColor?: string - formatColor?: string - buildingCode?: number - building?: string - buildingOrder?: number + borderColor?: string //地图内该店铺的box边框颜色 + formatColor?: string //地图内该店铺的box颜色 + buildingCode?: number //所属楼栋code + building?: string //所属楼栋名称 + buildingOrder?: number //所属楼栋编号 floorCode?: number - houseNumber?: string + houseNumber?: string //门牌号 contact?: string //联系方式 businessHours?: string //营业时间 - intro?: string - introEn?: string + intro?: string //店铺简介 + introEn?: string //简介英文 industryFatherCode?: string //父业态code industryFatherName?: string //父业态 industryUrl?: string //父业态icon @@ -37,7 +37,7 @@ declare interface Shop { thirdKouCode?: number //口碑ID thirdMeiCode?: number //美味不用等ID thirdZhiCode?: number //智石ID - doorMaterialList?: string[] - foodMaterialList?: string[] - activityList?: Activity[] + doorMaterialList?: string[] //店铺简介图 + foodMaterialList?: string[] //美食素材图 + activityList?: Activity[] //店铺活动图 } diff --git a/src/utils/Class/Brand.ts b/src/utils/Class/Brand.ts index cbfb32b..dfd4961 100644 --- a/src/utils/Class/Brand.ts +++ b/src/utils/Class/Brand.ts @@ -1,4 +1,4 @@ -type PickShop = Pick +type PickShop = Pick /** * Creates an instance of Shop. * @param {*} { shopName, floorOrder, floor, logoUrl, yaxis } @@ -10,11 +10,13 @@ export default class Brand { floor: string logoUrl: string yaxis: number | string - constructor({ shopName, floorOrder, floor, logoUrl, yaxis }: PickShop) { + shopCode: string | number + constructor({ shopName, floorOrder, floor, logoUrl, yaxis, shopCode }: PickShop) { this.shopName = shopName this.floorOrder = floorOrder this.floor = floor this.logoUrl = logoUrl this.yaxis = yaxis + this.shopCode = shopCode } } diff --git a/src/views/Guide/Guide.vue b/src/views/Guide/Guide.vue index 8097b69..150675f 100644 --- a/src/views/Guide/Guide.vue +++ b/src/views/Guide/Guide.vue @@ -3,15 +3,11 @@ diff --git a/src/views/Nav/Nav.vue b/src/views/Nav/Nav.vue index 6a673f0..cc29ed1 100644 --- a/src/views/Nav/Nav.vue +++ b/src/views/Nav/Nav.vue @@ -3,21 +3,21 @@