sen
1 天以前 7ed2a032d0724e68aec8af940f2ce0023a9f0eb7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
import { getPageConfig, PAGES } from './page.config'
 
/**
 * 路由导航工具
 * 统一管理页面跳转,处理参数传递和返回逻辑
 */
 
/**
 * 跳转到指定页面
 * @param {string|Object} page - 页面键名或页面配置对象
 * @param {Object} params - 跳转参数
 * @param {boolean} redirect - 是否使用 redirectTo(关闭当前页面)
 */
export const navigateTo = (page, params = {}, redirect = false) => {
  // 如果传入的是字符串键名,从配置中获取
  const pageConfig = typeof page === 'string' ? getPageConfig(page) : page
 
  if (!pageConfig || !pageConfig.path) {
    console.error('页面配置不存在:', page)
    return
  }
 
  // 构建 URL 参数(兼容微信小程序)
  const queryParts = []
 
  // 自动添加来源页面信息用于返回
  const pages = getCurrentPages()
  const currentPage = pages[pages.length - 1]
  if (currentPage && pageConfig.backTo !== false) {
    const currentRoute = '/' + currentPage.route
    // 如果目标页面配置了 backTo,使用配置;否则使用当前页面
    if (!params.from && !pageConfig.backTo) {
      params.from = currentRoute
    }
  }
 
  // 处理动态标题
  if (pageConfig.getTitle && params.type) {
    params.title = pageConfig.getTitle(params.type)
  } else if (pageConfig.title && !params.title) {
    params.title = pageConfig.title
  }
 
  // 将参数添加到 URL(只对 key 编码,value 保持原样以支持中文判断)
  Object.keys(params).forEach(key => {
    if (params[key] !== undefined && params[key] !== null) {
      const value = params[key]
      // 如果 value 包含中文或特殊字符,不编码
      // 这样目标页面可以直接判断中文字符
      queryParts.push(`${encodeURIComponent(key)}=${value}`)
    }
  })
 
  const url = pageConfig.path + (queryParts.length ? '?' + queryParts.join('&') : '')
 
 
  if (redirect) {
    uni.redirectTo({ url })
  } else {
    uni.navigateTo({ url })
  }
}
 
/**
 * 返回上一页
 * @param {number} delta - 返回层数,默认 1
 */
export const navigateBack = (delta = 1) => {
  const pages = getCurrentPages()
 
  if (pages.length > 1) {
    uni.navigateBack({ delta })
  } else {
    // 如果没有上一页,回到首页
    switchTab(PAGES.BE_REFERRED)
  }
}
 
/**
 * 根据配置返回指定页面
 * @param {string} backTo - 返回目标路径
 */
export const navigateToBack = (backTo) => {
  if (!backTo) {
    navigateBack()
    return
  }
 
  // 如果是完整路径,提取路径部分
  const path = backTo.split('?')[0]
  const pageConfig = Object.values(PAGES).find(p => p.path === path || p.path === '/' + path)
 
  if (pageConfig) {
    uni.navigateTo({ url: pageConfig.path })
  } else {
    // 自定义返回路径
    uni.navigateTo({ url: backTo.startsWith('/') ? backTo : '/' + backTo })
  }
}
 
/**
 * 跳转到 tabBar 页面
 * @param {string|Object} page - 页面键名或页面配置
 */
export const switchTab = (page) => {
  const pageConfig = typeof page === 'string' ? getPageConfig(page) : page
 
  if (pageConfig && pageConfig.path) {
    uni.switchTab({ url: pageConfig.path })
  }
}
 
/**
 * 关闭所有页面跳转到指定页面
 * @param {string|Object} page - 页面键名或页面配置
 * @param {Object} params - 参数
 */
export const reLaunch = (page, params = {}) => {
  const pageConfig = typeof page === 'string' ? getPageConfig(page) : page
 
  if (!pageConfig || !pageConfig.path) {
    console.error('页面配置不存在:', page)
    return
  }
 
  const queryParts = []
  Object.keys(params).forEach(key => {
    if (params[key] !== undefined && params[key] !== null) {
      queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
    }
  })
 
  const url = pageConfig.path + (queryParts.length ? '?' + queryParts.join('&') : '')
 
  uni.reLaunch({ url })
}
 
/**
 * 获取当前页面参数
 * @returns {Object} 页面参数
 */
export const getPageParams = () => {
  const pages = getCurrentPages()
  const currentPage = pages[pages.length - 1]
 
  if (!currentPage) return {}
 
  // #ifdef MP-WEIXIN
  return currentPage.options || {}
  // #endif
 
  // #ifdef H5
  const query = window.location.search.substring(1)
  const params = {}
  query.split('&').forEach(pair => {
    const [key, value] = pair.split('=')
    if (key) {
      params[key] = decodeURIComponent(value || '')
    }
  })
  return params
  // #endif
 
  // #ifdef APP-PLUS
  return currentPage.$page?.options || {}
  // #endif
}
 
/**
 * 解析页面参数(兼容 onLoad 的参数格式)
 * @param {Object} options - onLoad 接收的参数
 * @returns {Object} 解析后的参数
 */
export const parsePageParams = (options = {}) => {
  const params = {}
  Object.keys(options).forEach(key => {
    try {
      // 尝试解码
      params[key] = decodeURIComponent(options[key])
    } catch (e) {
      params[key] = options[key]
    }
  })
  return params
}
 
/**
 * 路由守卫 - 检查登录状态
 * @param {Function} callback - 未登录时的回调
 */
export const checkAuth = (callback) => {
  const token = uni.getStorageSync('token')
  if (!token) {
    if (callback) {
      callback()
    } else {
      navigateTo(PAGES.LOGIN, {}, true)
    }
    return false
  }
  return true
}
 
// 从 page.config.js 重新导出 PAGES
export { PAGES } from './page.config'
 
// 默认导出
export default {
  navigateTo,
  navigateBack,
  navigateToBack,
  switchTab,
  reLaunch,
  getPageParams,
  parsePageParams,
  checkAuth,
  PAGES
}