From 0fabacd71c7faeb1f87e238b8289c90590854a25 Mon Sep 17 00:00:00 2001 From: ZF sun <34314687@qq.com> Date: Thu, 30 Oct 2025 16:57:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(core):=20=E5=A2=9E=E5=BC=BA=E6=A0=B8?= =?UTF-8?q?=E5=BF=83=E4=BA=8B=E4=BB=B6=E9=80=9A=E8=AE=AF=E6=80=BB=E7=BA=BF?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=BC=BA=E8=B7=A8=E7=BB=84=E4=BB=B6=E4=BA=A4?= =?UTF-8?q?=E4=BA=92=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/js/diy.js | 1221 +++++++++++---------- common/js/dom-event-bridge.js | 133 +++ common/js/event-bus.js | 260 +++++ components/diy-components/diy-picture.vue | 165 +-- components/diy-components/minx.js | 8 + main.js | 124 ++- pages/index/index.vue | 8 +- pages/index/public/js/index.js | 22 + 8 files changed, 1191 insertions(+), 750 deletions(-) create mode 100644 common/js/dom-event-bridge.js create mode 100644 common/js/event-bus.js create mode 100644 components/diy-components/minx.js diff --git a/common/js/diy.js b/common/js/diy.js index f30445f..ab4a29f 100644 --- a/common/js/diy.js +++ b/common/js/diy.js @@ -1,611 +1,612 @@ -import WxMap from 'common/js/map-wx-jssdk.js'; -import Config from '@/common/js/config.js'; - -let systemInfo = uni.getSystemInfoSync(); -export default { - data() { - return { - diyData: { - global: { - title: '', - popWindow: { - imageUrl: '', - count: -1, - link: {}, - imgWidth: '', - imgHeight: '' - } - } - }, - id: 0, - name: '', - - topIndexValue: null, - statusBarHeight: systemInfo.statusBarHeight, - collectTop: 44, - showTip: false, - mpCollect: false, - mpShareData: null, //小程序分享数据 - scrollTop: 0, // 滚动位置 - paddingTop: (44 + systemInfo.statusBarHeight) + 'px', - marginTop: -(44 + systemInfo.statusBarHeight) + 'px', - followOfficialAccount: null, // 关注公众号组件 - - latitude: null, // 纬度 - longitude: null, // 经度 - currentPosition: '', // 当前位置 - nearestStore: null, // 离自己最近的门店 - - storeTimeOut: null, // 没有获取到定位,则获取默认门店 - locationModule: '', // 模式,locationPicker H5选择地图 - - diyRoute: '', // 页面路由 - openBottomNav: false, - isShowCopyRight: false, - - //启动广告 - adv:{}, - - }; - }, - onLoad(option) { - uni.hideTabBar(); - - if (option.source_member) uni.setStorageSync('source_member', option.source_member); - - // 小程序扫码进入 - if (option.scene) { - var sceneParams = decodeURIComponent(option.scene); - sceneParams = sceneParams.split('&'); - if (sceneParams.length) { - sceneParams.forEach(item => { - if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]); - }); - } - } - - // #ifdef H5 - // H5地图选择位置回调数据 - if (option.module && option.module == 'locationPicker') { - option.name = ''; // 清空地址 - this.locationModule = option.module; - this.latitude = option.latng.split(',')[0]; - this.longitude = option.latng.split(',')[1]; - } - // #endif - - this.id = option.id || 0; - this.name = option.name || ''; - - uni.removeStorageSync('manual_store_info'); // 清除手动切换门店缓存 - uni.removeStorageSync('manual_change_store'); // 清楚手动切换门店标识 - - // H5才会执行 - if (this.locationModule == 'locationPicker') { - - // H5地图选址后的回调 - this.getNearestStore(); - this.getCurrentLocation(); - - } else if (this.mapConfig.wap_is_open == 1) { - - // 每次都要定位,获取当前位置 - /*this.$util.getLocation({ - fail: (res) => { - // 拒绝定位,进入默认总店 - this.enterDefaultStore(); - } - });*/ - - // 如果3秒没有获取到定位,则获取默认门店,H5使用 - // #ifdef H5 - this.storeTimeOut = setTimeout(() => { - this.enterDefaultStore(); - }, 1000 * 3); - // #endif - - } else { - // 关闭定位 - this.enterDefaultStore(); - } - - }, - onShow() { - - this.init(); - }, - onHide() { - if (this.storeTimeOut) { - clearTimeout(this.storeTimeOut); - } - - // 跳转页面要关闭门店弹出框 - this.closeChooseStorePopup(); - - // 清除限时秒杀定时器 - this.$store.commit('setDiySeckillInterval', 0); - }, - computed: { - bgColor() { - let str = ''; - if (this.diyData && this.diyData.global) { - str = this.diyData.global.pageBgColor; - } - return str; - }, - bgImg() { - let str = ''; - if (this.diyData && this.diyData.global) { - str = this.diyData.global.topNavBg ? 'url(' + this.$util.img(this.diyData.global.bgUrl) + ')' : this.diyData.global.pageBgColor; - } - return str; - }, - bgUrl() { - let str = ''; - if (this.diyData && this.diyData.global) { - str = this.diyData.global.topNavBg ? 'transparent' : this.diyData.global.bgUrl; - } - return str; - }, - backgroundUrl() { - var str = this.diyData.global.bgUrl && this.diyData.global.bgUrl != 'transparent' ? 'url(' + this.$util.img(this.diyData.global.bgUrl) + ') ' : ''; - return str; - }, - textNavColor() { - if (this.diyData && this.diyData.global && this.diyData.global.textNavColor) { - return this.diyData.global.textNavColor; - } else { - return '#ffffff'; - } - }, - //计算首页弹框的显示宽高 - popWindowStyle() { - // 做大展示宽高 - let max_width = 290; - let max_height = 410; - // 参照宽高 - let refer_width = 290; - let refer_height = 290; - - let scale = this.diyData.global.popWindow.imgHeight / this.diyData.global.popWindow.imgWidth; - let width, height; - if (scale < refer_height / refer_width) { - width = max_width; - height = width * scale; - } else { - height = max_height; - width = height / scale; - } - - let obj = ''; - if (this.diyData.global.popWindow && this.diyData.global.popWindow.count != -1 && this.diyData.global.popWindow.imageUrl) { - obj += 'height:' + (height * 2) + 'rpx;'; - obj += 'width:' + (width * 2) + 'rpx;'; - } - return obj; - } - }, - watch: { - location: function (nVal) { - if (nVal) { - this.latitude = nVal.latitude; - this.longitude = nVal.longitude; - this.getNearestStore(); - this.getCurrentLocation(); - } - } - }, - methods: { - play(){ - console.log(123) - }, - async init() { - - // 定位信息过期后,重新获取定位 - if(this.mapConfig.wap_is_open == 1 && this.locationStorage && this.locationStorage.is_expired) { - this.$util.getLocation({ - fail: (res) => { - // 拒绝定位,进入默认总店 - this.enterDefaultStore(); - } - }); - } - - if (this.storeToken) { - //记录分享关系 - if (uni.getStorageSync('source_member')) { - this.$util.onSourceMember(uni.getStorageSync('source_member')); - } - } - - await this.getDiyInfo(); - //获取启动广告 - await this.getDiyAdv(); - - this.$store.commit('setDiySeckillInterval', 1); - - //小程序分享 - // #ifdef MP-WEIXIN - this.$util.getMpShare().then(res => { - this.mpShareData = res; - }); - // #endif - - let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店 - if (manualChangeStore) { - uni.removeStorageSync('manual_change_store'); - - // 滚动至顶部 - uni.pageScrollTo({ - duration: 200, - scrollTop: 0 - }); - } - }, - callback() { - if (this.$refs.indexPage) { - this.$refs.indexPage.initPageIndex(); - } - }, - //计算高度 - getHeight() { - // #ifdef H5 - if (this.diyData && this.diyData.global && this.diyData.global.navBarSwitch) { - // H5端,导航栏样式1 2 3不显示,要减去高度 - if ([1, 2, 3].indexOf(parseInt(this.diyData.global.navStyle)) != -1) { - this.paddingTop = 0; - this.marginTop = 0; - } - } - // #endif - - // #ifdef MP || APP-PLUS - let time = setInterval(() => { - this.$nextTick(() => { - const query = uni.createSelectorQuery().in(this); - query.select('.page-header').boundingClientRect(data => { - if (data && data.height) { - // 从状态栏高度开始算 - this.paddingTop = data.height + 'px'; - this.marginTop = -data.height + 'px'; - clearInterval(time); - } - }).exec(); - }); - }, 50); - // #endif - }, - async getDiyAdv(){ - //启动广告 - let res = await this.$api.sendRequest({ - url: '/api/diyview/getstartadv', - data: {}, - async: false - }); - this.adv = res.value - // 弹框形式,首次弹出 1,每次弹出 0 - if(this.adv.advshow == 1){ - setTimeout(() => { - if (res.value.advtype == 1) { - var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count'); - if ((this.$refs.uniPopupWindow && popwindow_count == '') || ( - this.$refs.uniPopupWindow && popwindow_count == 1)) { - - this.$refs.uniPopupWindow.open(); - uni.setStorageSync(this.id + this.name + '_popwindow_count', 1); - } - } else if (res.value.advtype == 0) { - this.$refs.uniPopupWindow.open(); - uni.setStorageSync(this.id + this.name + '_popwindow_count', 0); - } - }, 500); - } - - }, - async getDiyInfo() { - let res = await this.$api.sendRequest({ - url: '/api/diyview/info', - data: { - id: this.id, - name: this.name, - en_type:uni.getStorageSync("lang"),//获取语言底部 - }, - async: false - }); - if (res.code != 0 || !res.data) { - if (this.$refs.loadingCover) this.$refs.loadingCover.hide(); - - if (res.code == -3) { - this.$util.showToast({ - title: res.message - }); - this.diyData = {}; - return; - } - - this.$util.showToast({ - title: '未配置自定义页面数据' - }); - this.diyData = {}; - return; - } - - let diyDataValue = res.data; - if (diyDataValue.value) { - this.diyData = JSON.parse(diyDataValue.value); - this.$langConfig.title(this.diyData.global.title); - this.mpCollect = this.diyData.global.mpCollect; - this.setPublicShare(); - /* if (this.diyData.global.popWindow && this.diyData.global.popWindow.imageUrl) { - // 弹框形式,首次弹出 1,每次弹出 0 - setTimeout(() => { - if (this.diyData.global.popWindow.count == 1) { - var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count'); - if ((this.$refs.uniPopupWindow && popwindow_count == '') || ( - this.$refs.uniPopupWindow && popwindow_count == 1)) { - this.$refs.uniPopupWindow.open(); - uni.setStorageSync(this.id + this.name + '_popwindow_count', 1); - } - } else if (this.diyData.global.popWindow.count == 0) { - this.$refs.uniPopupWindow.open(); - uni.setStorageSync(this.id + this.name + '_popwindow_count', 0); - } - }, 500); - }*/ - - // 修改diy数据结构排序 - let searchIndex = -1; - let topCategoryIndex = -1; - this.diyData.value.forEach((item, index) => { - if (item.componentName == 'Search') { - if (item.positionWay == 'fixed') { - searchIndex = index; - } - } - if (item.componentName == 'TopCategory') { - topCategoryIndex = index; - } - }) - if (searchIndex != -1 && topCategoryIndex != -1) { - let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1); - let topCategoryData = this.diyData.value.slice(topCategoryIndex, topCategoryIndex + 1); - this.diyData.value.splice(searchIndex, 1); - if (searchIndex > topCategoryIndex) { - this.diyData.value.splice(topCategoryIndex, 1); - this.diyData.value.splice(0, 0, ...topCategoryData); - this.diyData.value.splice(1, 0, ...searchData); - } else - this.diyData.value.splice(0, 0, ...searchData); - } else if (searchIndex != -1 && topCategoryIndex == -1) { - let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1); - this.diyData.value.splice(searchIndex, 1); - this.diyData.value.splice(0, 0, ...searchData); - } - - for (var i = 0; i < this.diyData.value.length; i++) { - // 分类导航组件 - if (this.diyData.value[i].componentName == 'TopCategory') { - this.topIndexValue = this.diyData.value[i]; - this.topIndexValue.moduleIndex = i; //设置定位索引,根据此来确定定位顺序 - this.diyData.value.splice(i, 1); - continue; - } - - // 关注公众号组件 - if (this.diyData.value[i].componentName == 'FollowOfficialAccount') { - this.followOfficialAccount = this.diyData.value[i]; - // #ifdef H5 - this.diyData.value.splice(i, 1); - // #endif - continue; - } - - } - - // #ifdef MP - //小程序收藏 - if (!uni.getStorageSync('isCollect') && this.diyData.global.mpCollect) { - this.$refs.collectPopupWindow.open(); - this.showTip = true; - } - // #endif - - this.getHeight(); - if (this.diyData && this.diyData.global) { - this.openBottomNav = this.diyData.global.openBottomNav; - } - this.isShowCopyRight = true; - } - }, - closePopupWindow() { - this.$refs.uniPopupWindow.close(); - uni.setStorageSync(this.id + this.name + '_popwindow_count', -1); - }, - closeCollectPopupWindow() { - this.$refs.collectPopupWindow.close(); - uni.setStorageSync('isCollect', true); - }, - uniPopupWindowFn() { - this.$util.diyRedirectTo(this.diyData.global.popWindow.link); - this.closePopupWindow(); - }, - openChooseStorePopup() { - if (this.globalStoreConfig && this.globalStoreConfig.confirm_popup_control == 1) { - let storeInfo = this.globalStoreInfo; - - // 首次进入门店,没有门店信息 || 当前位置的门店和缓存门店不一致要弹框 - if (!storeInfo || storeInfo && this.nearestStore && storeInfo.store_id != this.nearestStore.store_id) { - if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.open(); - } - } - - let manualStoreInfo = uni.getStorageSync('manual_store_info'); // 手动选择门店 - if (manualStoreInfo) { - this.nearestStore = manualStoreInfo; - } - this.changeStore(this.nearestStore); // 切换门店数据 - }, - closeChooseStorePopup() { - if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.close(); - }, - // 确认进入门店 - enterStore() { - this.closeChooseStorePopup(); - }, - // 选择其他门店 - chooseOtherStore() { - this.$util.redirectTo('/pages_tool/store/list'); - this.closeChooseStorePopup(); - }, - // 打开地图重新选择位置 - reposition() { - // #ifdef MP - /*uni.chooseLocation({ - success: res => { - this.latitude = res.latitude; - this.longitude = res.longitude; - this.currentPosition = res.name; - this.getNearestStore(); - this.getCurrentLocation(); - }, - fail(res) { - uni.getSetting({ - success: function (res) { - var statu = res.authSetting; - if (!statu['scope.userLocation']) { - uni.showModal({ - title: '是否授权当前位置', - content: '需要获取您的地理位置,请确认授权,否则地图功能将无法使用', - success(tip) { - if (tip.confirm) { - uni.openSetting({ - success: function (data) { - if (data.authSetting['scope.userLocation'] === true) { - this.$util.showToast({ - title: '授权成功' - }); - //授权成功之后,再调用chooseLocation选择地方 - setTimeout(function () { - uni.chooseLocation({ - success: data => { - this.latitude = res.latitude; - this.longitude = res.longitude; - this.currentPosition = res.name; - this.getNearestStore(); - this.getCurrentLocation(); - } - }); - }, 1000); - } - } - }); - } else { - this.$util.showToast({ - title: '授权失败' - }); - } - } - }); - } - } - }); - } - });*/ - // #endif - - // #ifdef H5 - let backurl = Config.h5Domain; // 地图选择位置后的回调页面路径 - window.location.href = 'https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=' + - encodeURIComponent(backurl) + '&key=' + Config.mpKey + '&referer=myapp'; - // #endif - }, - // 获取离自己最近的一个门店 - getNearestStore() { - let data = {}; - if (this.latitude && this.longitude) { - data.latitude = this.latitude; - data.longitude = this.longitude; - } - this.$api.sendRequest({ - url: '/api/store/nearestStore', - data: data, - success: res => { - if (res.code == 0 && res.data) { - this.nearestStore = res.data; - this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address; - this.openChooseStorePopup(); - } - } - }); - }, - // 根据经纬度获取位置 - getCurrentLocation() { - var _this = this; - let data = {}; - if (this.latitude && this.longitude) { - data.latitude = this.latitude; - data.longitude = this.longitude; - } - - this.$api.sendRequest({ - url: '/api/store/getLocation', - data: data, - success: res => { - if (res.code == 0 && res.data) { - this.currentPosition = res.data.formatted_addresses.recommend; // 结合知名地点形成的描述性地址,更具人性化特点 - } else { - this.currentPosition = '未获取到定位'; - } - } - }); - }, - // 定位失败,进入默认门店 - enterDefaultStore() { - if (this.defaultStoreInfo) { - if (!this.nearestStore) { - this.nearestStore = this.defaultStoreInfo; - this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address; - } - if (this.currentPosition == '') this.currentPosition = '未获取到定位'; - this.openChooseStorePopup(); - } - }, - // 设置公众号分享 - setPublicShare() { - let shareUrl = this.$config.h5Domain + this.diyRoute; - if (this.id) shareUrl += '?id=' + this.id; - else if (this.name) shareUrl += '?name=' + this.name; - this.$util.setPublicShare({ - title: this.diyData.global.title, - desc: '', - link: shareUrl, - imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : '' - }); - } - }, - onPageScroll(e) { - this.scrollTop = e.scrollTop; - if (this.$refs.topNav) { - if (e.scrollTop >= 20) { - this.$refs.topNav.navTopBg(); - } else { - this.$refs.topNav.unSetnavTopBg(); - } - } - }, - // 下拉刷新 - onPullDownRefresh() { - this.$store.commit('setComponentRefresh'); - setTimeout(() => { - uni.stopPullDownRefresh(); - }, 50); - }, - // 分享给好友 - onShareAppMessage() { - return this.mpShareData.appMessage; - }, - // 分享到朋友圈 - onShareTimeline() { - return this.mpShareData.timeLine; - } +import WxMap from 'common/js/map-wx-jssdk.js'; +import Config from '@/common/js/config.js'; + +let systemInfo = uni.getSystemInfoSync(); +export default { + data() { + return { + // 自定义页面的数据,数据来源于后台配置 + diyData: { + global: { + title: '', + popWindow: { + imageUrl: '', + count: -1, + link: {}, + imgWidth: '', + imgHeight: '' + } + } + }, + id: 0, + name: '', + + topIndexValue: null, + statusBarHeight: systemInfo.statusBarHeight, + collectTop: 44, + showTip: false, + mpCollect: false, + mpShareData: null, //小程序分享数据 + scrollTop: 0, // 滚动位置 + paddingTop: (44 + systemInfo.statusBarHeight) + 'px', + marginTop: -(44 + systemInfo.statusBarHeight) + 'px', + followOfficialAccount: null, // 关注公众号组件 + + latitude: null, // 纬度 + longitude: null, // 经度 + currentPosition: '', // 当前位置 + nearestStore: null, // 离自己最近的门店 + + storeTimeOut: null, // 没有获取到定位,则获取默认门店 + locationModule: '', // 模式,locationPicker H5选择地图 + + diyRoute: '', // 页面路由 + openBottomNav: false, + isShowCopyRight: false, + + //启动广告 + adv:{}, + + }; + }, + onLoad(option) { + uni.hideTabBar(); + + if (option.source_member) uni.setStorageSync('source_member', option.source_member); + + // 小程序扫码进入 + if (option.scene) { + var sceneParams = decodeURIComponent(option.scene); + sceneParams = sceneParams.split('&'); + if (sceneParams.length) { + sceneParams.forEach(item => { + if (item.indexOf('m') != -1) uni.setStorageSync('source_member', item.split('-')[1]); + }); + } + } + + // #ifdef H5 + // H5地图选择位置回调数据 + if (option.module && option.module == 'locationPicker') { + option.name = ''; // 清空地址 + this.locationModule = option.module; + this.latitude = option.latng.split(',')[0]; + this.longitude = option.latng.split(',')[1]; + } + // #endif + + this.id = option.id || 0; + this.name = option.name || ''; + + uni.removeStorageSync('manual_store_info'); // 清除手动切换门店缓存 + uni.removeStorageSync('manual_change_store'); // 清楚手动切换门店标识 + + // H5才会执行 + if (this.locationModule == 'locationPicker') { + + // H5地图选址后的回调 + this.getNearestStore(); + this.getCurrentLocation(); + + } else if (this.mapConfig.wap_is_open == 1) { + + // 每次都要定位,获取当前位置 + /*this.$util.getLocation({ + fail: (res) => { + // 拒绝定位,进入默认总店 + this.enterDefaultStore(); + } + });*/ + + // 如果3秒没有获取到定位,则获取默认门店,H5使用 + // #ifdef H5 + this.storeTimeOut = setTimeout(() => { + this.enterDefaultStore(); + }, 1000 * 3); + // #endif + + } else { + // 关闭定位 + this.enterDefaultStore(); + } + + }, + onShow() { + + this.init(); + }, + onHide() { + if (this.storeTimeOut) { + clearTimeout(this.storeTimeOut); + } + + // 跳转页面要关闭门店弹出框 + this.closeChooseStorePopup(); + + // 清除限时秒杀定时器 + this.$store.commit('setDiySeckillInterval', 0); + }, + computed: { + bgColor() { + let str = ''; + if (this.diyData && this.diyData.global) { + str = this.diyData.global.pageBgColor; + } + return str; + }, + bgImg() { + let str = ''; + if (this.diyData && this.diyData.global) { + str = this.diyData.global.topNavBg ? 'url(' + this.$util.img(this.diyData.global.bgUrl) + ')' : this.diyData.global.pageBgColor; + } + return str; + }, + bgUrl() { + let str = ''; + if (this.diyData && this.diyData.global) { + str = this.diyData.global.topNavBg ? 'transparent' : this.diyData.global.bgUrl; + } + return str; + }, + backgroundUrl() { + var str = this.diyData.global.bgUrl && this.diyData.global.bgUrl != 'transparent' ? 'url(' + this.$util.img(this.diyData.global.bgUrl) + ') ' : ''; + return str; + }, + textNavColor() { + if (this.diyData && this.diyData.global && this.diyData.global.textNavColor) { + return this.diyData.global.textNavColor; + } else { + return '#ffffff'; + } + }, + //计算首页弹框的显示宽高 + popWindowStyle() { + // 做大展示宽高 + let max_width = 290; + let max_height = 410; + // 参照宽高 + let refer_width = 290; + let refer_height = 290; + + let scale = this.diyData.global.popWindow.imgHeight / this.diyData.global.popWindow.imgWidth; + let width, height; + if (scale < refer_height / refer_width) { + width = max_width; + height = width * scale; + } else { + height = max_height; + width = height / scale; + } + + let obj = ''; + if (this.diyData.global.popWindow && this.diyData.global.popWindow.count != -1 && this.diyData.global.popWindow.imageUrl) { + obj += 'height:' + (height * 2) + 'rpx;'; + obj += 'width:' + (width * 2) + 'rpx;'; + } + return obj; + } + }, + watch: { + location: function (nVal) { + if (nVal) { + this.latitude = nVal.latitude; + this.longitude = nVal.longitude; + this.getNearestStore(); + this.getCurrentLocation(); + } + } + }, + methods: { + play(){ + console.log(123) + }, + async init() { + + // 定位信息过期后,重新获取定位 + if(this.mapConfig.wap_is_open == 1 && this.locationStorage && this.locationStorage.is_expired) { + this.$util.getLocation({ + fail: (res) => { + // 拒绝定位,进入默认总店 + this.enterDefaultStore(); + } + }); + } + + if (this.storeToken) { + //记录分享关系 + if (uni.getStorageSync('source_member')) { + this.$util.onSourceMember(uni.getStorageSync('source_member')); + } + } + + await this.getDiyInfo(); + //获取启动广告 + await this.getDiyAdv(); + + this.$store.commit('setDiySeckillInterval', 1); + + //小程序分享 + // #ifdef MP-WEIXIN + this.$util.getMpShare().then(res => { + this.mpShareData = res; + }); + // #endif + + let manualChangeStore = uni.getStorageSync('manual_change_store'); // 手动切换门店 + if (manualChangeStore) { + uni.removeStorageSync('manual_change_store'); + + // 滚动至顶部 + uni.pageScrollTo({ + duration: 200, + scrollTop: 0 + }); + } + }, + callback() { + if (this.$refs.indexPage) { + this.$refs.indexPage.initPageIndex(); + } + }, + //计算高度 + getHeight() { + // #ifdef H5 + if (this.diyData && this.diyData.global && this.diyData.global.navBarSwitch) { + // H5端,导航栏样式1 2 3不显示,要减去高度 + if ([1, 2, 3].indexOf(parseInt(this.diyData.global.navStyle)) != -1) { + this.paddingTop = 0; + this.marginTop = 0; + } + } + // #endif + + // #ifdef MP || APP-PLUS + let time = setInterval(() => { + this.$nextTick(() => { + const query = uni.createSelectorQuery().in(this); + query.select('.page-header').boundingClientRect(data => { + if (data && data.height) { + // 从状态栏高度开始算 + this.paddingTop = data.height + 'px'; + this.marginTop = -data.height + 'px'; + clearInterval(time); + } + }).exec(); + }); + }, 50); + // #endif + }, + async getDiyAdv(){ + //启动广告 + let res = await this.$api.sendRequest({ + url: '/api/diyview/getstartadv', + data: {}, + async: false + }); + this.adv = res.value + // 弹框形式,首次弹出 1,每次弹出 0 + if(this.adv.advshow == 1){ + setTimeout(() => { + if (res.value.advtype == 1) { + var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count'); + if ((this.$refs.uniPopupWindow && popwindow_count == '') || ( + this.$refs.uniPopupWindow && popwindow_count == 1)) { + + this.$refs.uniPopupWindow.open(); + uni.setStorageSync(this.id + this.name + '_popwindow_count', 1); + } + } else if (res.value.advtype == 0) { + this.$refs.uniPopupWindow.open(); + uni.setStorageSync(this.id + this.name + '_popwindow_count', 0); + } + }, 500); + } + + }, + async getDiyInfo() { + let res = await this.$api.sendRequest({ + url: '/api/diyview/info', + data: { + id: this.id, + name: this.name, + en_type:uni.getStorageSync("lang"),//获取语言底部 + }, + async: false + }); + if (res.code != 0 || !res.data) { + if (this.$refs.loadingCover) this.$refs.loadingCover.hide(); + + if (res.code == -3) { + this.$util.showToast({ + title: res.message + }); + this.diyData = {}; + return; + } + + this.$util.showToast({ + title: '未配置自定义页面数据' + }); + this.diyData = {}; + return; + } + + let diyDataValue = res.data; + if (diyDataValue.value) { + this.diyData = JSON.parse(diyDataValue.value); + this.$langConfig.title(this.diyData.global.title); + this.mpCollect = this.diyData.global.mpCollect; + this.setPublicShare(); + /* if (this.diyData.global.popWindow && this.diyData.global.popWindow.imageUrl) { + // 弹框形式,首次弹出 1,每次弹出 0 + setTimeout(() => { + if (this.diyData.global.popWindow.count == 1) { + var popwindow_count = uni.getStorageSync(this.id + this.name + '_popwindow_count'); + if ((this.$refs.uniPopupWindow && popwindow_count == '') || ( + this.$refs.uniPopupWindow && popwindow_count == 1)) { + this.$refs.uniPopupWindow.open(); + uni.setStorageSync(this.id + this.name + '_popwindow_count', 1); + } + } else if (this.diyData.global.popWindow.count == 0) { + this.$refs.uniPopupWindow.open(); + uni.setStorageSync(this.id + this.name + '_popwindow_count', 0); + } + }, 500); + }*/ + + // 修改diy数据结构排序 + let searchIndex = -1; + let topCategoryIndex = -1; + this.diyData.value.forEach((item, index) => { + if (item.componentName == 'Search') { + if (item.positionWay == 'fixed') { + searchIndex = index; + } + } + if (item.componentName == 'TopCategory') { + topCategoryIndex = index; + } + }) + if (searchIndex != -1 && topCategoryIndex != -1) { + let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1); + let topCategoryData = this.diyData.value.slice(topCategoryIndex, topCategoryIndex + 1); + this.diyData.value.splice(searchIndex, 1); + if (searchIndex > topCategoryIndex) { + this.diyData.value.splice(topCategoryIndex, 1); + this.diyData.value.splice(0, 0, ...topCategoryData); + this.diyData.value.splice(1, 0, ...searchData); + } else + this.diyData.value.splice(0, 0, ...searchData); + } else if (searchIndex != -1 && topCategoryIndex == -1) { + let searchData = this.diyData.value.slice(searchIndex, searchIndex + 1); + this.diyData.value.splice(searchIndex, 1); + this.diyData.value.splice(0, 0, ...searchData); + } + + for (var i = 0; i < this.diyData.value.length; i++) { + // 分类导航组件 + if (this.diyData.value[i].componentName == 'TopCategory') { + this.topIndexValue = this.diyData.value[i]; + this.topIndexValue.moduleIndex = i; //设置定位索引,根据此来确定定位顺序 + this.diyData.value.splice(i, 1); + continue; + } + + // 关注公众号组件 + if (this.diyData.value[i].componentName == 'FollowOfficialAccount') { + this.followOfficialAccount = this.diyData.value[i]; + // #ifdef H5 + this.diyData.value.splice(i, 1); + // #endif + continue; + } + + } + + // #ifdef MP + //小程序收藏 + if (!uni.getStorageSync('isCollect') && this.diyData.global.mpCollect) { + this.$refs.collectPopupWindow.open(); + this.showTip = true; + } + // #endif + + this.getHeight(); + if (this.diyData && this.diyData.global) { + this.openBottomNav = this.diyData.global.openBottomNav; + } + this.isShowCopyRight = true; + } + }, + closePopupWindow() { + this.$refs.uniPopupWindow.close(); + uni.setStorageSync(this.id + this.name + '_popwindow_count', -1); + }, + closeCollectPopupWindow() { + this.$refs.collectPopupWindow.close(); + uni.setStorageSync('isCollect', true); + }, + uniPopupWindowFn() { + this.$util.diyRedirectTo(this.diyData.global.popWindow.link); + this.closePopupWindow(); + }, + openChooseStorePopup() { + if (this.globalStoreConfig && this.globalStoreConfig.confirm_popup_control == 1) { + let storeInfo = this.globalStoreInfo; + + // 首次进入门店,没有门店信息 || 当前位置的门店和缓存门店不一致要弹框 + if (!storeInfo || storeInfo && this.nearestStore && storeInfo.store_id != this.nearestStore.store_id) { + if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.open(); + } + } + + let manualStoreInfo = uni.getStorageSync('manual_store_info'); // 手动选择门店 + if (manualStoreInfo) { + this.nearestStore = manualStoreInfo; + } + this.changeStore(this.nearestStore); // 切换门店数据 + }, + closeChooseStorePopup() { + if (this.$refs.chooseStorePopup) this.$refs.chooseStorePopup.close(); + }, + // 确认进入门店 + enterStore() { + this.closeChooseStorePopup(); + }, + // 选择其他门店 + chooseOtherStore() { + this.$util.redirectTo('/pages_tool/store/list'); + this.closeChooseStorePopup(); + }, + // 打开地图重新选择位置 + reposition() { + // #ifdef MP + /*uni.chooseLocation({ + success: res => { + this.latitude = res.latitude; + this.longitude = res.longitude; + this.currentPosition = res.name; + this.getNearestStore(); + this.getCurrentLocation(); + }, + fail(res) { + uni.getSetting({ + success: function (res) { + var statu = res.authSetting; + if (!statu['scope.userLocation']) { + uni.showModal({ + title: '是否授权当前位置', + content: '需要获取您的地理位置,请确认授权,否则地图功能将无法使用', + success(tip) { + if (tip.confirm) { + uni.openSetting({ + success: function (data) { + if (data.authSetting['scope.userLocation'] === true) { + this.$util.showToast({ + title: '授权成功' + }); + //授权成功之后,再调用chooseLocation选择地方 + setTimeout(function () { + uni.chooseLocation({ + success: data => { + this.latitude = res.latitude; + this.longitude = res.longitude; + this.currentPosition = res.name; + this.getNearestStore(); + this.getCurrentLocation(); + } + }); + }, 1000); + } + } + }); + } else { + this.$util.showToast({ + title: '授权失败' + }); + } + } + }); + } + } + }); + } + });*/ + // #endif + + // #ifdef H5 + let backurl = Config.h5Domain; // 地图选择位置后的回调页面路径 + window.location.href = 'https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=' + + encodeURIComponent(backurl) + '&key=' + Config.mpKey + '&referer=myapp'; + // #endif + }, + // 获取离自己最近的一个门店 + getNearestStore() { + let data = {}; + if (this.latitude && this.longitude) { + data.latitude = this.latitude; + data.longitude = this.longitude; + } + this.$api.sendRequest({ + url: '/api/store/nearestStore', + data: data, + success: res => { + if (res.code == 0 && res.data) { + this.nearestStore = res.data; + this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address; + this.openChooseStorePopup(); + } + } + }); + }, + // 根据经纬度获取位置 + getCurrentLocation() { + var _this = this; + let data = {}; + if (this.latitude && this.longitude) { + data.latitude = this.latitude; + data.longitude = this.longitude; + } + + this.$api.sendRequest({ + url: '/api/store/getLocation', + data: data, + success: res => { + if (res.code == 0 && res.data) { + this.currentPosition = res.data.formatted_addresses.recommend; // 结合知名地点形成的描述性地址,更具人性化特点 + } else { + this.currentPosition = '未获取到定位'; + } + } + }); + }, + // 定位失败,进入默认门店 + enterDefaultStore() { + if (this.defaultStoreInfo) { + if (!this.nearestStore) { + this.nearestStore = this.defaultStoreInfo; + this.nearestStore.show_address = this.nearestStore.full_address.replace(/,/g, ' ') + ' ' + this.nearestStore.address; + } + if (this.currentPosition == '') this.currentPosition = '未获取到定位'; + this.openChooseStorePopup(); + } + }, + // 设置公众号分享 + setPublicShare() { + let shareUrl = this.$config.h5Domain + this.diyRoute; + if (this.id) shareUrl += '?id=' + this.id; + else if (this.name) shareUrl += '?name=' + this.name; + this.$util.setPublicShare({ + title: this.diyData.global.title, + desc: '', + link: shareUrl, + imgUrl: this.siteInfo ? this.$util.img(this.siteInfo.logo_square) : '' + }); + } + }, + onPageScroll(e) { + this.scrollTop = e.scrollTop; + if (this.$refs.topNav) { + if (e.scrollTop >= 20) { + this.$refs.topNav.navTopBg(); + } else { + this.$refs.topNav.unSetnavTopBg(); + } + } + }, + // 下拉刷新 + onPullDownRefresh() { + this.$store.commit('setComponentRefresh'); + setTimeout(() => { + uni.stopPullDownRefresh(); + }, 50); + }, + // 分享给好友 + onShareAppMessage() { + return this.mpShareData.appMessage; + }, + // 分享到朋友圈 + onShareTimeline() { + return this.mpShareData.timeLine; + } } \ No newline at end of file diff --git a/common/js/dom-event-bridge.js b/common/js/dom-event-bridge.js new file mode 100644 index 0000000..31c1bb5 --- /dev/null +++ b/common/js/dom-event-bridge.js @@ -0,0 +1,133 @@ +/** + * Uniapp DOM 事件桥接类,用于将 DOM 事件桥接到 EventBus + * 支持将 DOM 事件转换为 EventBus 事件,可配置是否阻止默认行为和停止传播 + * + * @author ZFSun + * @version 1.0.0 + * @createTime 2023-08-10 + */ + +class DomEventBridge { + constructor() { + this.eventBus = null + this.domListeners = new Map() + } + + // 设置 EventBus 实例 + setEventBus(eventBus) { + this.eventBus = eventBus + } + + // 桥接 DOM 事件到 EventBus + bridgeDomEvent(domEventName, eventBusEventName, options = {}) { + const handler = (domEvent) => { + if (!this.eventBus) return + + // 创建 EventBus 兼容的事件对象 + const eventBusEvent = this.createEventBusEvent(domEvent, eventBusEventName) + + // 触发 EventBus 事件 + const shouldContinue = this.eventBus.emit(eventBusEventName, eventBusEvent) + + // 根据 EventBus 处理结果决定是否阻止 DOM 事件默认行为 + if (!shouldContinue && options.preventDefault) { + domEvent.preventDefault() + } + + // 根据 EventBus 处理结果决定是否停止 DOM 事件传播 + if (!shouldContinue && options.stopPropagation) { + domEvent.stopPropagation() + } + } + + // 保存监听器引用以便清理 + const listenerKey = `${domEventName}-${eventBusEventName}` + this.domListeners.set(listenerKey, handler) + + // 添加 DOM 事件监听 + // #ifdef H5 + document.addEventListener(domEventName, handler, options) + // #endif + + return () => this.unbridgeDomEvent(domEventName, eventBusEventName) + } + + // 创建 EventBus 兼容的事件对象 + createEventBusEvent(domEvent, eventBusEventName) { + return { + type: eventBusEventName, + domEvent: domEvent, + originalEvent: domEvent, + target: domEvent.target, + currentTarget: domEvent.currentTarget, + timestamp: Date.now(), + + // EventBus 的取消方法 + preventDefault: function () { + this._preventDefault = true + }, + + stopPropagation: function () { + this._stopPropagation = true + }, + + // DOM 事件的代理方法 + stopImmediatePropagation: function () { + domEvent.stopImmediatePropagation() + }, + + get isDefaultPrevented() { + return this._preventDefault || false + }, + + get isPropagationStopped() { + return this._stopPropagation || false + } + } + } + + // 取消桥接 + unbridgeDomEvent(domEventName, eventBusEventName) { + const listenerKey = `${domEventName}-${eventBusEventName}` + const handler = this.domListeners.get(listenerKey) + + if (handler) { + // #ifdef H5 + document.removeEventListener(domEventName, handler) + // #endif + this.domListeners.delete(listenerKey) + } + } + + // 从 EventBus 触发 DOM 事件 + triggerDomEventFromEventBus(domEventName, detail = {}) { + // #ifdef H5 + const event = new CustomEvent(domEventName, { + bubbles: true, + cancelable: true, + detail: detail + }) + + document.dispatchEvent(event) + return !event.defaultPrevented + // #endif + + // #ifdef MP - WEIXIN + // 小程序环境不支持 DOM 事件 + return true + // #endif + } + + // 清理所有桥接 + destroy() { + for (const [listenerKey, handler] of this.domListeners) { + const [domEventName] = listenerKey.split('-') + // #ifdef H5 + document.removeEventListener(domEventName, handler) + // #endif + } + this.domListeners.clear() + } +} + +export default new DomEventBridge() \ No newline at end of file diff --git a/common/js/event-bus.js b/common/js/event-bus.js new file mode 100644 index 0000000..df6b9d1 --- /dev/null +++ b/common/js/event-bus.js @@ -0,0 +1,260 @@ +/** + * Uniapp 事件总线类,用于在应用内进行事件通信 + * 支持同步和异步事件触发,可配置是否继续传播事件 + * 可配置是否在任意监听器抛出错误后立即停止传播 + * 可配置是否在每个监听器执行后调用 defaultAsyncHandler + * 如果 allowAsyncHandlerRun 为 true,在每个监听器执行后调用 defaultAsyncHandler + * 如果 allowAsyncHandlerRun 为 false,不调用 defaultAsyncHandler + * 注意:如果 allowAsyncHandlerRun 为 false,defaultAsyncHandler 不会被调用,也不会等待其 resolve + * + * @author ZFSun + * @version 1.0.0 + * @createTime 2023-08-10 + */ + +class EventBus { + constructor() { + this.events = new Map() + this.domBridge = null + this.platform = this.detectPlatform() + } + + // 检测平台 + detectPlatform() { + // #ifdef H5 + return 'h5' + // #endif + + // #ifdef MP-WEIXIN + return 'weapp' + // #endif + + return 'unknown' + } + + // 设置 DOM 桥接 + setDomBridge(bridge) { + this.domBridge = bridge + bridge.setEventBus(this) + } + + // 监听事件(自动处理平台差异),支持取消 + on(eventName, callback, options = { priority: 0 }) { + // 如果是 H5 平台且事件名是 DOM 事件,自动创建桥接 + if (this.platform === 'h5' && this.isDomEvent(eventName) && this.domBridge) { + return this.domBridge.bridgeDomEvent( + this.getDomEventName(eventName), + eventName, + options + ) + } + + // 普通 EventBus 监听 + if (!this.events.has(eventName)) { + this.events.set(eventName, new Set()) + } + + const handler = { callback, options } + this.events.get(eventName).add(handler) + + // 返回取消函数 + return () => this.off(eventName, handler) + } + + // 监听多个事件,支持取消 + onMany(eventNames = [], callback, options = { priority: 0 }) { + // 支持字符串数组或空格分隔的字符串,自动转换为数组 + if (typeof eventNames === 'string') { + // 支持使用空格分隔事件名 + // 支持使用逗号分隔事件名 + // 下面代码使用正则表达式,自动处理逗号和空格分隔的字符串 + eventNames = eventNames.replace(/\s+/g, ',').split(',') + } + const removeFns = eventNames.map(eventName => this.on(eventName, callback, options)) + return () => removeFns.forEach(fn => fn()) + } + + + // 异步触发事件,支持取消传播,并支持在监听处理后调用异步函数 defaultAsyncHandler + // 使用方式:await eventBus.emit(eventName, data, defaultAsyncHandler) + // defaultAsyncHandler 会在每个监听器执行后被调用,签名为 defaultAsyncHandler(event, handler, handlerResult) + // 如果 defaultAsyncHandler 返回 Promise,会等待其 resolve + // 如果 allowContinuePropagation 为 false,事件触发后将立即返回,不继续传播 + // 如果 stopOnError 为 true,在任意监听器抛出错误后立即停止传播 + // 如果 allowAsyncHandlerRun 为 true,在每个监听器执行后调用 defaultAsyncHandler + // 如果 allowAsyncHandlerRun 为 false,不调用 defaultAsyncHandler + // 注意:如果 allowAsyncHandlerRun 为 false,defaultAsyncHandler 不会被调用,也不会等待其 resolve + async emit(eventName, data, defaultAsyncHandler, { allowContinuePropagation = true, stopOnError = false, allowAsyncHandlerRun = true } = {}) { + // 先创建事件对象,方便传入 defaultAsyncHandler + const event = this.createEvent(eventName, data) + + // helper to call defaultAsyncHandler only when allowed + const callDefaultAsyncHandler = async (evt, handler, handlerResult) => { + if (typeof defaultAsyncHandler !== 'function' || !allowAsyncHandlerRun) return + try { + const res = defaultAsyncHandler(evt, handler, handlerResult) + if (res instanceof Promise) { + const awaited = await res + if (awaited === false) evt.preventDefault() + } else { + if (res === false) evt.preventDefault() + } + } catch (err) { + console.error(`EventBus defaultAsyncHandler error for ${eventName}:`, err) + } + } + + // 如果是 H5 平台且需要触发 DOM 事件 + if (this.platform === 'h5' && data && data.triggerDomEvent) { + const domResult = this.domBridge.triggerDomEventFromEventBus( + this.getDomEventName(eventName), + data.detail + ) + + // 调用 defaultAsyncHandler(仅当允许) + await callDefaultAsyncHandler(event, null, domResult) + + // 如果不允许继续传播,则直接返回(根据 defaultPrevented 判断结果) + if (!allowContinuePropagation) { + return !event.defaultPrevented + } + // 否则继续走普通 EventBus 处理(fallthrough) + } + + // 普通 EventBus 触发 + const handlers = this.events.get(eventName) + + // 如果没有监听器,执行 defaultAsyncHandler(如果有),并返回结果 + if (!handlers) { + await callDefaultAsyncHandler(event, null, true) + return !event.defaultPrevented + } + + // 如果不允许继续传播,则不执行任何监听器,只调用一次 defaultAsyncHandler(若提供),然后返回 + if (!allowContinuePropagation) { + await callDefaultAsyncHandler(event, null, true) + return !event.defaultPrevented + } + + // 按优先级排序执行 + const sortedHandlers = Array.from(handlers).sort((a, b) => { + return (b.options?.priority || 0) - (a.options?.priority || 0) + }) + + // 按优先级顺序执行每个监听器 + for (const handler of sortedHandlers) { + if (event.defaultPrevented) break + + try { + // 支持监听器返回 Promise 或同步值 + const result = handler.callback(event) + const awaitedResult = result instanceof Promise ? await result : result + + // 如果回调返回 false,也停止默认行为 + if (awaitedResult === false) { + event.preventDefault() + } + + // 在每个监听器执行后,如果允许并且提供了 defaultAsyncHandler,就调用并等待它 + await callDefaultAsyncHandler(event, handler, awaitedResult) + } catch (error) { + console.error(`EventBus ${eventName} error:`, error) + // 如果全局或该 handler 指定遇错停止传播,则停止 + if (stopOnError || handler.options?.stopOnError) { + break + } + // 否则继续下一个 handler + } + + // 一次性监听自动移除 + if (handler.options?.once) { + this.off(eventName, handler) + } + } + + return !event.defaultPrevented + } + + + // 移除监听 + off(eventName, handler) { + const handlers = this.events.get(eventName) + if (handlers) { + handlers.delete(handler) + if (handlers.size === 0) { + this.events.delete(eventName) + } + } + } + + // 移除多个事件监听 + offMany(eventNames, handler) { + eventNames.forEach(eventName => this.off(eventName, handler)) + } + + // 移除所有监听 + offAll(eventName) { + this.events.delete(eventName) + } + + // 一次性监听 + once(eventName, callback, options = {}) { + return this.on(eventName, callback, { ...options, once: true }) + } + + // 前置监听(高优先级) + preOn(eventName, callback) { + return this.on(eventName, callback, { priority: 100 }) + } + + // 后置监听(低优先级) + postOn(eventName, callback) { + return this.on(eventName, callback, { priority: -100 }) + } + + // 判断是否是 DOM 事件 + isDomEvent(eventName) { + const domEvents = ['click', 'touchstart', 'touchend', 'mousedown', 'mouseup'] + return domEvents.includes(eventName.toLowerCase()) + } + + // 获取对应的 DOM 事件名 + getDomEventName(eventName) { + const map = { + 'tap': 'click', + 'click': 'click', + 'touchstart': 'touchstart', + 'touchend': 'touchend' + } + return map[eventName] || eventName + } + + // 创建可取消的事件对象 + createEvent(eventName, data) { + const event = { + type: eventName, + data, + timestamp: Date.now(), + defaultPrevented: false, + _isPropagationStopped: false + } + + // 阻止事件继续传播 + event.preventDefault = function () { + this.defaultPrevented = true + } + + // 停止传播 + event.stopPropagation = function () { + this._isPropagationStopped = true + } + + event.isPropagationStopped = function () { + return this._isPropagationStopped + } + + return event + } +} + +export default new EventBus() \ No newline at end of file diff --git a/components/diy-components/diy-picture.vue b/components/diy-components/diy-picture.vue index ce49f83..f39aaa7 100644 --- a/components/diy-components/diy-picture.vue +++ b/components/diy-components/diy-picture.vue @@ -1,77 +1,90 @@ - - - - - \ No newline at end of file diff --git a/components/diy-components/minx.js b/components/diy-components/minx.js new file mode 100644 index 0000000..dd09d69 --- /dev/null +++ b/components/diy-components/minx.js @@ -0,0 +1,8 @@ +export default { + methods: { + // 异步触发事件 + async __$emitEvent(payload = {eventName: '__unnamedEvent', data: {}, promiseCallback: null}) { + await this.$eventBus?.emit(payload.eventName, payload.data, payload.promiseCallback) + }, + } +} \ No newline at end of file diff --git a/main.js b/main.js index 3354500..caad937 100644 --- a/main.js +++ b/main.js @@ -1,59 +1,67 @@ -// #ifdef H5 -import './common/js/pc' -// #endif -import Vue from 'vue' -import App from './App' -import store from './store' -import Util from './common/js/util.js' -import Http from './common/js/http.js' -import Lang from './common/js/lang.js' -import Config from './common/js/config.js' -import globalConfig from './common/js/golbalConfig.js'; -import { - uniStorage -} from './common/js/storage.js' - -Vue.prototype.$store = store //挂在vue - -Vue.config.productionTip = false - -Vue.prototype.$util = Util; -Vue.prototype.$api = Http; - -Vue.prototype.$langConfig = Lang; //语言包对象 -Vue.prototype.$lang = Lang.lang; //解析语言包 - -Vue.prototype.$config = Config; - -Vue.mixin(globalConfig); - -App.mpType = 'app'; - -// 重写存储,增加前缀 -uniStorage(); - -//常用组件 -import loadingCover from '@/components/loading-cover/loading-cover.vue'; -Vue.component('loading-cover', loadingCover); - -import nsEmpty from '@/components/ns-empty/ns-empty.vue'; -Vue.component('ns-empty', nsEmpty); - -import MescrollUni from "@/components/mescroll/my-list-mescroll.vue"; -Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件 - -import MescrollBody from "@/components/mescroll/mescroll-body.vue" -Vue.component('mescroll-body', MescrollBody); - -import NsLogin from "@/components/ns-login/ns-login.vue" -Vue.component('ns-login', NsLogin); - -import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue'; -Vue.component('privacy-popup', PrivacyPopup) - -const app = new Vue({ - ...App, - store -}) - +// #ifdef H5 +import './common/js/pc' +// #endif +import Vue from 'vue' +import App from './App' +import store from './store' +import Util from './common/js/util.js' +import Http from './common/js/http.js' +import Lang from './common/js/lang.js' +import Config from './common/js/config.js' +import EventBus from './common/js/event-bus.js' +import DomEventBridge from './common/js/dom-event-bridge.js' +import globalConfig from './common/js/golbalConfig.js'; +import { + uniStorage +} from './common/js/storage.js' + +Vue.prototype.$store = store //挂在vue + +Vue.config.productionTip = false + +Vue.prototype.$util = Util; +Vue.prototype.$api = Http; + +Vue.prototype.$langConfig = Lang; //语言包对象 +Vue.prototype.$lang = Lang.lang; //解析语言包 + +Vue.prototype.$config = Config; + + +// #ifdef H5 +EventBus.setDomBridge(DomEventBridge) +// #endif +Vue.prototype.$eventBus = EventBus; + +Vue.mixin(globalConfig); + +App.mpType = 'app'; + +// 重写存储,增加前缀 +uniStorage(); + +//常用组件 +import loadingCover from '@/components/loading-cover/loading-cover.vue'; +Vue.component('loading-cover', loadingCover); + +import nsEmpty from '@/components/ns-empty/ns-empty.vue'; +Vue.component('ns-empty', nsEmpty); + +import MescrollUni from "@/components/mescroll/my-list-mescroll.vue"; +Vue.component("mescroll-uni", MescrollUni); //上拉加载,下拉刷新组件 + +import MescrollBody from "@/components/mescroll/mescroll-body.vue" +Vue.component('mescroll-body', MescrollBody); + +import NsLogin from "@/components/ns-login/ns-login.vue" +Vue.component('ns-login', NsLogin); + +import PrivacyPopup from '@/components/wx-privacy-popup/privacy-popup.vue'; +Vue.component('privacy-popup', PrivacyPopup) + +const app = new Vue({ + ...App, + store +}) + app.$mount() \ No newline at end of file diff --git a/pages/index/index.vue b/pages/index/index.vue index a7e499c..2fad2c5 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -127,6 +127,7 @@ + @@ -140,17 +141,12 @@ export default { - data() { - return { - minScrollTop: 100, // 设置回到顶端按钮显示要求,最小滚动距离 - } - }, components: { uniPopup, nsNavbar, toTop }, - mixins: [diyJs, indexJs, scroll] + mixins: [diyJs, scroll, indexJs] }; diff --git a/pages/index/public/js/index.js b/pages/index/public/js/index.js index 8432be7..930104e 100644 --- a/pages/index/public/js/index.js +++ b/pages/index/public/js/index.js @@ -1,6 +1,7 @@ export default { data() { return { + minScrollTop: 100, // 设置回到顶端按钮显示要求,最小页面滚动距离 wechatQrcode: '', // 公众号二维码 diyRoute: '/pages/index/index' }; @@ -16,8 +17,17 @@ export default { }, onShow() { + // 获取关注公众号二维码 this.getFollowQrcode(); }, + mounted() { + // 监听图片点击事件 + this.unsubscribe = this.$eventBus?.on('pictureTap', this._handleDiyGroupInteractionEvent); + }, + beforeDestroy() { + // 移除图片点击事件监听 + if (this.unsubscribe) this.unsubscribe(); + }, methods: { // 关注公众号 getFollowQrcode() { @@ -37,5 +47,17 @@ export default { officialAccountsClose() { this.$refs.officialAccountsPopup.close(); }, + // 统一处理点击及触摸事件 + _handleDiyGroupInteractionEvent(payload) { + if (this.storeToken) { + return; + } + + // 打开登录弹窗 + this.$refs.login?.open(); + + // 阻止事件继续传播 + return false; + } } } \ No newline at end of file