import { Platform } from './platform.js'; // 内部 helper:获取当前页面实例 const _getCurrentPage = () => { const pages = getCurrentPages(); return pages.length === 0 ? null : pages[pages.length - 1]; }; // 内部 helper:获取当前页面路由(统一提取 route 或 $page.path) const _getCurrentRoute = (currentPage) => { if (!currentPage) return ''; if (currentPage.route) return currentPage.route; if (currentPage.$page && currentPage.$page.path) return currentPage.$page.path; return ''; }; // 内部 helper:判断 tabBarList 是否已加载且有 list 配置 const _isValidTabBarList = (tabBarList) => { return tabBarList && tabBarList.list; }; // 内部 helper:规范化路由:无前导斜杠时补全 const _normalizeLeadingSlash = (route) => { if (!route) return route; return route.startsWith('/') ? route : '/' + route; }; // 内部 helper:通过 $util 方法的安全调用 const _callUtil = (vm, method, ...args) => { if (vm.$util && vm.$util[method]) { return vm.$util[method](...args); } return null; }; export default { onLoad() { }, onShow() { // remote-only 小程序/鸿蒙: boot 未完成时跳过 refresh,避免空翻译写入标题等 // H5 不受影响(main.js 已 await boot 后才 $mount) if (this.$langConfig.isRemoteOnly && this.$langConfig.isRemoteOnly()) { if (!this.$langConfig.isBootCompleted || !this.$langConfig.isBootCompleted()) { return; } } // 刷新多语言(仅刷新标题,不触发全页面 $forceUpdate) // 全量刷新仅在语言包真正变化时由 lang.js emitUpdated 触发 this.$langConfig.refresh(false); // TabBar 根页面时隐藏系统导航栏的返回按钮 // (uni-app 的系统导航栏在通过 navigateTo 跳转到 tab 页时可能残留返回键) const tabBarList = this.$store.state.tabBarList; if (!_isValidTabBarList(tabBarList)) return; const currentRoute = _getCurrentRoute(_getCurrentPage()); if (!currentRoute) return; const isRoot = _callUtil(this, 'isTabBarRootPage', currentRoute, tabBarList) || false; if (isRoot) { // #ifdef MP-WEIXIN || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-ALIPAY try { uni.hideHomeButton(); } catch (e) { /* 兼容 */ } // #endif } }, computed: { // 是否是英文环境 isEnEnv() { return this.$langConfig.getCurrentLocale() === 'en-us'; }, // 是否是非中文环境(用于多语言商品名/字段切换) isNotZhEnv() { return this.$langConfig.getCurrentLocale() !== 'zh-cn'; }, // 动态判断:当前页面是否是 TabBar 根页面(tab 根页不应显示返回按钮) isTabRootPage() { const tabBarList = this.$store.state.tabBarList; if (!_isValidTabBarList(tabBarList)) return false; const currentRoute = _getCurrentRoute(_getCurrentPage()); if (!currentRoute) return false; return _callUtil(this, 'isTabBarRootPage', currentRoute, tabBarList) || false; }, themeStyle() { return this.$store.state.themeStyle; }, themeColor() { return this.$store.state.themeColor; }, // 插件是否存在 addonIsExist() { return this.$store.state.addonIsExist; }, tabBarList() { return this.$store.state.tabBarList; }, shouldShowTabBar() { const tabBarList = this.$store.state.tabBarList; if (!_isValidTabBarList(tabBarList)) return false; const mode = tabBarList.page_visibility_mode; const routeList = tabBarList.page_routes || []; if (!mode || mode === 'all') return true; if (mode === 'none') return false; const currentPage = _getCurrentPage(); if (!currentPage) return true; const currentRoute = _normalizeLeadingSlash(_getCurrentRoute(currentPage)); if (!currentRoute) return true; const inList = _callUtil(this, 'isPageInRouteList', currentRoute, routeList) || false; if (mode === 'whitelist') return inList; if (mode === 'blacklist') return !inList; return true; }, tabBarPagePaddingStyle() { return this.$util.objToStyle({ height: `calc(100vh - ${this.tabBarHeight})`, paddingBottom: this.tabBarHeight }); }, siteInfo() { return this.$store.state.siteInfo; }, memberInfo() { return this.$store.state.memberInfo; }, storeToken() { return this.$store.state.token; }, bottomNavHidden() { return this.$store.state.bottomNavHidden; }, globalStoreConfig() { return this.$store.state.globalStoreConfig; }, globalStoreInfo() { return this.$store.state.globalStoreInfo; }, // 定位信息 location() { return this.$store.state.location; }, // 定位信息(缓存) locationStorage() { let data = uni.getStorageSync('location'); if (data) { var date = new Date(); if (this.mapConfig.wap_valid_time > 0) { data.is_expired = (date.getTime() / 1000) > data.valid_time; // 是否过期 } else { data.is_expired = false; } } return data; }, // 默认总店(定位失败后使用) defaultStoreInfo() { return this.$store.state.defaultStoreInfo; }, // 组件刷新计数 componentRefresh() { return this.$store.state.componentRefresh; }, // AI客服配置 globalAIKefuConfig() { return this.$store.state.globalAIKefuConfig; }, // 客服配置 servicerConfig() { return this.$store.state.servicerConfig; }, // 企业微信配置 wxworkConfig() { return this.$store.state.wxworkConfig; }, diySeckillInterval() { return this.$store.state.diySeckillInterval; }, tabBarHeight() { return this.shouldShowTabBar ? this.$store.state.tabBarHeight : '0rpx'; }, mapConfig() { return this.$store.state.mapConfig; }, copyright() { let copyright = this.$store.state.copyright; // 判断是否授权 if (copyright && !copyright.auth) { copyright.logo = ''; copyright.copyright_link = ''; } return copyright; }, cartList() { return this.$store.state.cartList; }, cartIds() { return this.$store.state.cartIds; }, cartNumber() { return this.$store.state.cartNumber; }, cartMoney() { return this.$store.state.cartMoney; } }, methods: { /** * 当前平台类型(多端翻译隔离) * 复用 Platform.getAppType(),与服务端 /api/BaseApi 的 $app_type 对齐 */ getAppType() { try { return Platform.getAppType() || '*'; } catch (e) { return '*'; } }, // 颜色变浅(>0)、变深函数(<0) lightenDarkenColor(color, amount) { var usePound = false; if (color[0] == "#") { color = color.slice(1); usePound = true; } var num = parseInt(color, 16); var r = (num >> 16) + amount; if (r > 255) r = 255; else if (r < 0) r = 0; var b = ((num >> 8) & 0x00FF) + amount; if (b > 255) b = 255; else if (b < 0) b = 0; var g = (num & 0x0000FF) + amount; if (g > 255) g = 255; else if (g < 0) g = 0; return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16); }, /** * 切换门店 * @param {Object} info 门店信息 * @param {Object} isJump 是否跳转到首页 */ changeStore(info, isJump) { if (info) { this.$store.commit('setGlobalStoreInfo', info); } let route = this.$util.getCurrRoute(); if (isJump && route != 'pages/index/index') { uni.setStorageSync('manual_change_store', true); // 手动切换门店 this.$store.dispatch('getCartNumber'); //重新获取购物车数据 this.$util.redirectTo(this.$util.INDEX_PAGE_URL); } }, /** * 金额格式化输出 * @param {Object} money */ moneyFormat(money) { if (isNaN(parseFloat(money))) return money; return parseFloat(money).toFixed(2); }, /** * 重新定向到登录授权, 不区分生命周期 * @param {String} backUrl * @param {Object} params 附加参数 * @param {Function} effectFnc 副作用函数, 登录授权失败的处理方式 */ redirectTologin(backUrl = '', params = {}, effectFnc = ()=>{}) { console.log(`------> redirectTologin`, backUrl); setTimeout(() => { this.$nextTick(() => { let mode = 'navigateTo'; // #ifdef H5 || MP-HARMONY mode = 'redirectTo'; // H5必须使用redirectTo, 不然点击返回箭头无法返回。 // #endif this.$refs?.login?.open(backUrl, mode, effectFnc); }); }, 0); }, /** * 重新定向到登录授权, 当页面显示的时候, 失败后, * 原因:onLoad、onReady 只执行一次; * 而且,有的页面不需要这个功能 * @param {String} backUrl */ redirectTologinOnShowLifecycle(backUrl) { console.log(`------> redirectTologinOnShowLifecycle`, backUrl); // #ifdef H5 || MP-HARMONY this.redirectTologin(backUrl); // #endif // #ifdef MP-WEIXIN this.redirectTologin(backUrl, {}, () => { uni.navigateBack({delta: 1 }); }) // #endif } }, filters: { /** * 金额格式化输出 * @param {Object} money */ moneyFormat(money) { if (isNaN(parseFloat(money))) return money; return parseFloat(money).toFixed(2); } } }