/** * App 跳转参数处理 * 花开物业 App 通过 launchMiniProgram 的 extraData 传入支付参数和登录凭证, * 小程序通过 referrerInfo.extraData 接收(查询字符串格式)。 * * extraData 示例: * payAmount=10&acct=xxx&custId=xxx&token=xxx&userId=xxx&sign=xxx&... */ const STORAGE_KEY = 'app_launch_payment_data' const APP_QUERY_KEY = 'app_query_params' /** * 解析查询字符串为对象 */ function parseQueryString(str) { if (!str || typeof str !== 'string') return null const params = {} str.split('&').forEach(item => { const idx = item.indexOf('=') if (idx === -1) return const key = item.substring(0, idx) const val = item.substring(idx + 1) params[key] = decodeURIComponent(val || '') }) return params } /** * 从启动参数中获取 App 传入的全部数据(支付参数 + token + userId) */ export function captureAppLaunchData(onShowOptions) { let data = null let queryData = null const tryGetData = (options, label) => { if (!options) return null console.log(label, JSON.stringify(options)) // 保存 path query 参数(供接口调用) if (options.query && Object.keys(options.query).length > 0) { queryData = options.query console.log(label + ' path query 参数:', JSON.stringify(queryData)) } // 优先从 query 获取 if (options.query && Object.keys(options.query).length > 0) { return options.query } // referrerInfo.extraData:可能是对象也可能是查询字符串 const extraData = options?.referrerInfo?.extraData if (extraData) { if (typeof extraData === 'string') { console.log(label + ' extraData 是查询字符串,解析中...') return parseQueryString(extraData) } return extraData } return null } // 冷启动 try { data = tryGetData(wx.getLaunchOptionsSync?.() || {}, '冷启动') } catch (e) { console.error('getLaunchOptionsSync 失败:', e) } // 热启动 if (!data) { data = tryGetData(onShowOptions, '热启动') } if (data && (data.payAmount || data.acct || data.custId || data.billId)) { // 恢复登录态 if (data.token) { uni.setStorageSync('token', data.token) console.log('已恢复 token') } if (data.userId) { uni.setStorageSync('userId', data.userId) console.log('已恢复 userId') } uni.setStorageSync(STORAGE_KEY, data) console.log('已存储 App 支付数据:', JSON.stringify(data)) } // 单独保存参数供接口使用(优先 queryData,fallback 到 data,即 extraData 来源) const queryParams = queryData || data if (queryParams) { uni.setStorageSync(APP_QUERY_KEY, queryParams) console.log('已存储 App 接口参数:', JSON.stringify(queryParams)) } return data } /** 检查是否已登录(token 存在) */ export function isLoggedIn() { return !!uni.getStorageSync('token') } /** 获取 App 传入的支付数据 */ export function getAppPaymentData() { try { return uni.getStorageSync(STORAGE_KEY) || null } catch (e) { return null } } /** 获取 App 传入的 path query 参数(供接口调用) */ export function getAppQueryParams() { try { return uni.getStorageSync(APP_QUERY_KEY) || null } catch (e) { return null } } /** 清除 */ export function clearAppPaymentData() { uni.removeStorageSync(STORAGE_KEY) } /** 清除 path query 参数(在支付完成后调用) */ export function clearAppQueryParams() { uni.removeStorageSync(APP_QUERY_KEY) } /** 组装 paymentItem */ export function buildPaymentItemFromApp(appData) { if (!appData) return null const amount = Number(appData.payAmount || appData.orderAmount || 0).toFixed(2) const displayName = appData.goodName || appData.remark || appData.type || '缴费' return { ...appData, type: displayName, rechargeAmount: amount } }