|
|
@@ -0,0 +1,159 @@
|
|
|
+/**
|
|
|
+ * 太阳码 / 扫码进入参数解析(冷启动 onLoad + 热启动 App.onShow 共用)
|
|
|
+ */
|
|
|
+
|
|
|
+/** 微信「扫小程序码 / 长按识别 / 相册选取」等进入场景值 */
|
|
|
+export const SCAN_ENTRY_SCENES = [1011, 1012, 1013, 1047, 1048, 1049]
|
|
|
+
|
|
|
+/**
|
|
|
+ * 解析 scene 字符串为键值对,如 s=123&a=456&id=789
|
|
|
+ */
|
|
|
+export function parseSceneString(sceneRaw) {
|
|
|
+ if (!sceneRaw) {
|
|
|
+ return {}
|
|
|
+ }
|
|
|
+ const scene = decodeURIComponent(String(sceneRaw))
|
|
|
+ const params = {}
|
|
|
+ scene.split('&').forEach((pair) => {
|
|
|
+ if (!pair) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const eq = pair.indexOf('=')
|
|
|
+ if (eq === -1) {
|
|
|
+ params[pair] = ''
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const key = pair.slice(0, eq)
|
|
|
+ const val = pair.slice(eq + 1)
|
|
|
+ if (key) {
|
|
|
+ params[key] = val != null ? decodeURI(val) : ''
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return params
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 将 scene 内字段展开为页面 query(account / hdId / id 等)
|
|
|
+ */
|
|
|
+export function sceneParamsToQuery(sceneParams, baseQuery) {
|
|
|
+ const q = Object.assign({}, baseQuery || {})
|
|
|
+ if (sceneParams.s) {
|
|
|
+ q.account = sceneParams.s
|
|
|
+ }
|
|
|
+ if (sceneParams.a) {
|
|
|
+ if (!q.account) {
|
|
|
+ q.account = sceneParams.a
|
|
|
+ }
|
|
|
+ q.staffId = sceneParams.a
|
|
|
+ }
|
|
|
+ if (sceneParams.id) {
|
|
|
+ q.id = sceneParams.id
|
|
|
+ }
|
|
|
+ if (sceneParams.hdId) {
|
|
|
+ q.hdId = sceneParams.hdId
|
|
|
+ }
|
|
|
+ delete q.scene
|
|
|
+ return q
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 合并 onLoad 的 option:scene 展开 + 普通二维码 q 参数
|
|
|
+ */
|
|
|
+export function applyLaunchQuery(option) {
|
|
|
+ const merged = Object.assign({}, option || {})
|
|
|
+ if (merged.scene) {
|
|
|
+ const sceneParams = parseSceneString(merged.scene)
|
|
|
+ Object.assign(merged, sceneParamsToQuery(sceneParams, merged))
|
|
|
+ delete merged.scene
|
|
|
+ }
|
|
|
+ if (merged.q) {
|
|
|
+ const currentUrl = decodeURIComponent(String(merged.q))
|
|
|
+ const marker = 'account='
|
|
|
+ const idx = currentUrl.lastIndexOf(marker)
|
|
|
+ if (idx >= 0) {
|
|
|
+ let account = currentUrl.substring(idx + marker.length)
|
|
|
+ const amp = account.indexOf('&')
|
|
|
+ if (amp >= 0) {
|
|
|
+ account = account.substring(0, amp)
|
|
|
+ }
|
|
|
+ merged.account = account
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return merged
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 拼 reLaunch 地址
|
|
|
+ */
|
|
|
+export function buildLaunchUrl(path, query) {
|
|
|
+ const normalizedPath = path && path.indexOf('/') === 0 ? path : '/' + (path || '')
|
|
|
+ const parts = []
|
|
|
+ const q = query || {}
|
|
|
+ Object.keys(q).forEach((key) => {
|
|
|
+ const val = q[key]
|
|
|
+ if (val !== undefined && val !== null && val !== '') {
|
|
|
+ parts.push(key + '=' + encodeURIComponent(val))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ return parts.length ? normalizedPath + '?' + parts.join('&') : normalizedPath
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 写入 account / hdId / currentQuery(与原 globalMixins 一致)
|
|
|
+ */
|
|
|
+export function persistLaunchStorage(option) {
|
|
|
+ if (option.account) {
|
|
|
+ uni.setStorageSync('account', option.account)
|
|
|
+ } else {
|
|
|
+ uni.setStorageSync('account', 0)
|
|
|
+ }
|
|
|
+ if (option.hdId) {
|
|
|
+ uni.setStorageSync('hdId', option.hdId)
|
|
|
+ } else {
|
|
|
+ uni.setStorageSync('hdId', 0)
|
|
|
+ }
|
|
|
+ uni.setStorageSync('currentQuery', JSON.stringify(option))
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 热启动:根据 getEnterOptionsSync 判断是否需要 reLaunch 到展开 query 的目标页
|
|
|
+ * @returns {boolean} 是否已触发 reLaunch
|
|
|
+ */
|
|
|
+export function tryReLaunchFromScanEnter(globalData) {
|
|
|
+ if (!uni.getEnterOptionsSync) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ const enter = uni.getEnterOptionsSync()
|
|
|
+ if (!enter || !enter.query || !enter.query.scene) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ const launchKey = (enter.path || '') + '|' + enter.query.scene
|
|
|
+ const sceneCode = Number(enter.scene)
|
|
|
+ const isScanEntry = SCAN_ENTRY_SCENES.indexOf(sceneCode) >= 0
|
|
|
+
|
|
|
+ if (!isScanEntry && globalData.lastLaunchKey === launchKey) {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+
|
|
|
+ const sceneParams = parseSceneString(enter.query.scene)
|
|
|
+ const expandedQuery = sceneParamsToQuery(sceneParams, Object.assign({}, enter.query))
|
|
|
+ const targetUrl = buildLaunchUrl(enter.path, expandedQuery)
|
|
|
+ const targetRoute = (enter.path || '').replace(/^\//, '')
|
|
|
+
|
|
|
+ const pages = getCurrentPages()
|
|
|
+ const current = pages.length ? pages[pages.length - 1] : null
|
|
|
+ if (current) {
|
|
|
+ const curRoute = current.route || ''
|
|
|
+ const curOpts = current.options || {}
|
|
|
+ // 已在目标页且参数已展开(无 scene),无需重复 reLaunch
|
|
|
+ if (curRoute === targetRoute && !curOpts.scene && (curOpts.account || curOpts.id || curOpts.hdId)) {
|
|
|
+ globalData.lastLaunchKey = launchKey
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ globalData.lastLaunchKey = launchKey
|
|
|
+ uni.reLaunch({ url: targetUrl })
|
|
|
+ return true
|
|
|
+}
|