|
@@ -86,6 +86,7 @@ router.afterEach((to, from) => {
|
|
|
export default router
|
|
export default router
|
|
|
/**
|
|
/**
|
|
|
* 将 params 参数拼接到 path 路径后面
|
|
* 将 params 参数拼接到 path 路径后面
|
|
|
|
|
+ * 兼容扫码拉起小程序时 q 参数为编码后的 URL 的情况
|
|
|
* @param path 基础路径
|
|
* @param path 基础路径
|
|
|
* @param params 参数对象
|
|
* @param params 参数对象
|
|
|
* @returns 拼接后的完整路径
|
|
* @returns 拼接后的完整路径
|
|
@@ -95,11 +96,26 @@ function appendParamsToPath(path: string, params: Record<string, any>): string {
|
|
|
return path
|
|
return path
|
|
|
}
|
|
}
|
|
|
const queryParams: string[] = []
|
|
const queryParams: string[] = []
|
|
|
|
|
+
|
|
|
Object.entries(params).forEach(([key, value]) => {
|
|
Object.entries(params).forEach(([key, value]) => {
|
|
|
if (value !== undefined && value !== null) {
|
|
if (value !== undefined && value !== null) {
|
|
|
- // 对参数进行 URL 编码
|
|
|
|
|
|
|
+ const strValue = String(value)
|
|
|
|
|
+
|
|
|
|
|
+ // 处理扫码参数 q,可能是编码后的 URL
|
|
|
|
|
+ if (key === 'q') {
|
|
|
|
|
+ const extractedParams = extractParamsFromEncodedUrl(strValue)
|
|
|
|
|
+ if (extractedParams) {
|
|
|
|
|
+ // 将提取的参数合并到 queryParams
|
|
|
|
|
+ Object.entries(extractedParams).forEach(([k, v]) => {
|
|
|
|
|
+ queryParams.push(`${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
|
|
|
|
|
+ })
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 普通参数直接编码
|
|
|
const encodedKey = encodeURIComponent(key)
|
|
const encodedKey = encodeURIComponent(key)
|
|
|
- const encodedValue = encodeURIComponent(String(value))
|
|
|
|
|
|
|
+ const encodedValue = encodeURIComponent(strValue)
|
|
|
queryParams.push(`${encodedKey}=${encodedValue}`)
|
|
queryParams.push(`${encodedKey}=${encodedValue}`)
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
@@ -107,3 +123,59 @@ function appendParamsToPath(path: string, params: Record<string, any>): string {
|
|
|
const queryString = queryParams.join('&')
|
|
const queryString = queryParams.join('&')
|
|
|
return queryString ? `${path}?${queryString}` : path
|
|
return queryString ? `${path}?${queryString}` : path
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * 从编码后的 URL 中提取查询参数
|
|
|
|
|
+ * @param encodedUrl 可能被编码的 URL 字符串
|
|
|
|
|
+ * @returns 解析后的查询参数对象,如果不是有效的 URL 则返回 null
|
|
|
|
|
+ */
|
|
|
|
|
+function extractParamsFromEncodedUrl(encodedUrl: string): Record<string, string> | null {
|
|
|
|
|
+ try {
|
|
|
|
|
+ // 尝试解码 URL
|
|
|
|
|
+ let decodedUrl = encodedUrl
|
|
|
|
|
+ // 可能需要多次解码(处理多次编码的情况)
|
|
|
|
|
+ while (decodedUrl.includes('%')) {
|
|
|
|
|
+ const newDecoded = decodeURIComponent(decodedUrl)
|
|
|
|
|
+ if (newDecoded === decodedUrl)
|
|
|
|
|
+ break
|
|
|
|
|
+ decodedUrl = newDecoded
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否是有效的 URL 格式
|
|
|
|
|
+ if (!decodedUrl.includes('http://') && !decodedUrl.includes('https://')) {
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 提取 ? 后面的查询参数
|
|
|
|
|
+ const questionIndex = decodedUrl.indexOf('?')
|
|
|
|
|
+ if (questionIndex === -1) {
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const queryString = decodedUrl.substring(questionIndex + 1)
|
|
|
|
|
+ if (!queryString) {
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 解析查询参数
|
|
|
|
|
+ const params: Record<string, string> = {}
|
|
|
|
|
+ const pairs = queryString.split('&')
|
|
|
|
|
+
|
|
|
|
|
+ pairs.forEach((pair) => {
|
|
|
|
|
+ const equalIndex = pair.indexOf('=')
|
|
|
|
|
+ if (equalIndex > 0) {
|
|
|
|
|
+ const key = decodeURIComponent(pair.substring(0, equalIndex))
|
|
|
|
|
+ const val = decodeURIComponent(pair.substring(equalIndex + 1))
|
|
|
|
|
+ params[key] = val
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (pair) {
|
|
|
|
|
+ params[decodeURIComponent(pair)] = ''
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ return Object.keys(params).length > 0 ? params : null
|
|
|
|
|
+ }
|
|
|
|
|
+ catch {
|
|
|
|
|
+ return null
|
|
|
|
|
+ }
|
|
|
|
|
+}
|