Files
lucky_shop/common/js/navigation.js
ZF sun 4ae21c5d7a refactor: 完成多语言国际化全量替换与补充
1. 新增大量中英文语言包文件,覆盖自定义组件、页面、工具类的文案
2. 替换硬编码文本为多语言调用,统一全局文案管理
3. 优化语言包结构,拆分公共模块与业务模块
4. 修复部分语言加载与国际化适配问题
2026-06-26 17:32:35 +08:00

286 lines
7.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { EventSafety } from '@/common/js/event-safety.js'
import util from '@/common/js/util.js'
import Lang from '@/common/js/lang.js'
export class NavigationHelper {
constructor() {
this.navigationCache = new Map()
}
// 安全地获取导航栏高度
async getNavigationHeight(component, options = {}) {
const cacheKey = `nav_height`
// 检查缓存
if (this.navigationCache.has(cacheKey) && !options.forceRefresh) {
return this.navigationCache.get(cacheKey)
}
// 获取高度
try {
// 尝试直接获取 uni-page-head
const height = await this.getDirectNavigationHeight(component)
if (height > 0) {
this.navigationCache.set(cacheKey, height)
return height
}
// 备用方案:平台特定方法
const platformHeight = await this.getPlatformNavigationHeight()
this.navigationCache.set(cacheKey, platformHeight)
return platformHeight
} catch (error) {
console.warn('获取导航栏高度失败,使用默认值:', error)
const defaultHeight = this.getDefaultNavHeight()
this.navigationCache.set(cacheKey, defaultHeight)
return defaultHeight
}
}
// 直接查询导航栏高度
getDirectNavigationHeight(component) {
return new Promise((resolve) => {
const query = uni.createSelectorQuery().in(component)
query.select('.uni-page-head').boundingClientRect((rect) => {
if (rect && rect.height > 0) {
resolve(rect.height)
} else {
console.warn('未找到 uni-page-head 元素或高度为0')
resolve(0)
}
}).exec()
})
}
// 平台特定的高度获取
getPlatformNavigationHeight() {
return new Promise((resolve) => {
// #ifdef MP-WEIXIN
// 微信小程序精确计算
try {
const menuButtonInfo = wx.getMenuButtonBoundingClientRect()
let systemInfo = util.getDeviceInfo();
const height = menuButtonInfo.bottom +
(menuButtonInfo.top - systemInfo.statusBarHeight)
resolve(height)
} catch (error) {
console.error('微信小程序高度计算失败:', error)
resolve(44)
}
// #endif
// #ifdef H5
// H5环境:尝试获取自定义导航栏或使用默认值
if (typeof document !== 'undefined') {
const customNav = document.querySelector('.uni-page-head')
if (customNav) {
resolve(customNav.offsetHeight)
} else {
resolve(44) // 默认导航栏高度
}
} else {
resolve(44)
}
// #endif
// #ifdef APP-PLUS
// App端:状态栏 + 导航栏
try {
const statusBarHeight = plus.navigator.getStatusbarHeight()
resolve(statusBarHeight + 44)
} catch (error) {
console.error('App端高度获取失败:', error)
resolve(88)
}
// #endif
// 默认值
resolve(44)
})
}
// 获取默认高度
getDefaultHeight() {
// #ifdef MP-WEIXIN
return 44 // 微信小程序默认
// #endif
// #ifdef H5
return 44 // H5默认
// #endif
// #ifdef APP-PLUS
return 88 // App默认(状态栏44 + 导航栏44)
// #endif
return 44
}
// 获取状态栏高度
getStatusBarHeight() {
// #ifdef MP-WEIXIN
let systemInfo = util.getDeviceInfo();
return systemInfo.statusBarHeight || 20
// #endif
// #ifdef H5
return 0 // H5通常没有状态栏
// #endif
// #ifdef APP-PLUS
try {
return plus.navigator.getStatusbarHeight()
} catch (error) {
return 44
}
// #endif
return 0
}
// 获取安全区域
getSafeAreaInsets() {
try {
let systemInfo = util.getDeviceInfo();
return systemInfo.safeArea || {
top: 0,
bottom: 0,
left: 0,
right: 0
}
} catch (error) {
return {
top: 0,
bottom: 0,
left: 0,
right: 0
}
}
}
// 创建安全的事件处理器
createSafeEventHandler(handler, options = {}) {
return EventSafety.wrapEventHandler(handler, options)
}
// 安全地处理服务请求事件
createServiceRequestHandler(component) {
return this.createSafeEventHandler((event) => {
return this.handleServiceRequest(event, component)
}, {
onError: (error, event) => {
this.handleNavigationError(error, event, component)
}
})
}
// 处理服务请求
async handleServiceRequest(event, component) {
// 安全检查事件目标
if (this.shouldProcessNavigationRequest(event)) {
await this.processNavigationRequest(event, component)
}
}
// 检查是否应该处理导航请求
shouldProcessNavigationRequest(event) {
// 方法1:检查事件类型
if (event.type === 'service.requestComponentInfo') {
return true
}
// 方法2:检查目标元素
if (event.matches('.navigation-component') || event.matches('.uni-page-head')) {
return true
}
// 方法3:检查事件详情
if (event.detail && event.detail.componentType === 'navigation') {
return true
}
return false
}
// 处理导航请求
async processNavigationRequest(event, component) {
try {
// 获取导航栏信息
const navInfo = await this.getNavigationInfo(component)
// 发送响应
this.emitNavigationResponse(navInfo, component)
} catch (error) {
console.error('处理导航请求失败:', error)
throw error
}
}
// 获取完整的导航信息
async getNavigationInfo(component) {
const [navHeight, statusBarHeight, safeArea] = await Promise.all([
this.getNavigationHeight(component),
this.getStatusBarHeight(),
this.getSafeAreaInsets()
])
return {
navHeight,
statusBarHeight,
safeArea,
timestamp: Date.now()
}
}
// 发送导航响应
emitNavigationResponse(navInfo, component) {
if (component && component.$emit) {
component.$emit('navigation.infoResponse', {
success: true,
data: navInfo,
timestamp: Date.now()
})
}
}
// 错误处理
handleNavigationError(error, event, component) {
console.error('导航处理错误:', {
error: error.message,
eventType: event?.type,
component: component?.$options?.name
})
// 发送错误响应
if (component && component.$emit) {
component.$emit('navigation.infoError', {
success: false,
error: error.message,
timestamp: Date.now()
})
}
// 显示用户友好的错误信息
this.showError(Lang.lang('common.navigation.serviceUnavailable'))
}
// 显示错误提示
showError(message) {
uni.showToast({
title: message,
icon: 'none',
duration: 2000
})
}
// 清理缓存
clearCache() {
this.navigationCache.clear()
}
}
// 创建全局实例
const navigationHelper = new NavigationHelper()
export default navigationHelper