修改参数缓存bug
This commit is contained in:
@@ -14,10 +14,11 @@
|
|||||||
|
|
||||||
onShow((options) => {
|
onShow((options) => {
|
||||||
console.log('App onShow, options:', JSON.stringify(options))
|
console.log('App onShow, options:', JSON.stringify(options))
|
||||||
|
// 先判断是否为支付小程序返回:是则本次进入只按支付结果处理,
|
||||||
|
// 不能再走 App 跳转参数捕获,否则兜底参数会把上一次的账单写回缓存
|
||||||
|
if (capturePaymentResult(options)) return
|
||||||
// 捕获 App 跳转传入的支付参数(热启动 — options 携带新的 referrerInfo)
|
// 捕获 App 跳转传入的支付参数(热启动 — options 携带新的 referrerInfo)
|
||||||
captureAppLaunchData(options)
|
captureAppLaunchData(options)
|
||||||
// 捕获日照银行支付小程序返回的支付结果(navigateBackMiniProgram 的 extraData)
|
|
||||||
capturePaymentResult(options)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取 uniPush 2.0 CID
|
// 获取 uniPush 2.0 CID
|
||||||
|
|||||||
@@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
const STORAGE_KEY = 'app_launch_payment_data'
|
const STORAGE_KEY = 'app_launch_payment_data'
|
||||||
const APP_QUERY_KEY = 'app_query_params'
|
const APP_QUERY_KEY = 'app_query_params'
|
||||||
|
/** 页面缓存的缴费条目(arrearsPayment 页展示用) */
|
||||||
|
const PAYMENT_ITEM_KEY = 'arrearsPayment'
|
||||||
|
/** 日照银行支付小程序返回的原始结果 */
|
||||||
|
const PAYMENT_RESULT_KEY = 'payment_return_result'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 需要转为数组的参数字段(逗号分隔字符串 → 数组)
|
* 需要转为数组的参数字段(逗号分隔字符串 → 数组)
|
||||||
@@ -73,6 +77,8 @@ function normalizeBillParams(obj) {
|
|||||||
export function captureAppLaunchData(onShowOptions) {
|
export function captureAppLaunchData(onShowOptions) {
|
||||||
let data = null
|
let data = null
|
||||||
let queryData = null
|
let queryData = null
|
||||||
|
// 参数来源:current=本次进入 / enter=当前进入 / launch=冷启动兜底(热启动时仍是首次冷启动的旧值)
|
||||||
|
let dataSource = null
|
||||||
|
|
||||||
const tryGetData = (options, label) => {
|
const tryGetData = (options, label) => {
|
||||||
if (!options) return null
|
if (!options) return null
|
||||||
@@ -106,6 +112,7 @@ export function captureAppLaunchData(onShowOptions) {
|
|||||||
// 热启动再次从 App 进入时,getLaunchOptionsSync 仍返回首次冷启动的旧值,
|
// 热启动再次从 App 进入时,getLaunchOptionsSync 仍返回首次冷启动的旧值,
|
||||||
// 若先读它会导致新 token 被旧 token 覆盖,因此这里以本次 options 为准。
|
// 若先读它会导致新 token 被旧 token 覆盖,因此这里以本次 options 为准。
|
||||||
data = tryGetData(onShowOptions, '本次进入')
|
data = tryGetData(onShowOptions, '本次进入')
|
||||||
|
if (data) dataSource = 'current'
|
||||||
|
|
||||||
// 兜底:本次 options 未取到数据时,依次尝试当前进入参数、冷启动参数。
|
// 兜底:本次 options 未取到数据时,依次尝试当前进入参数、冷启动参数。
|
||||||
// 注意:不能以 !onShowOptions 判断,onLaunch/onShow 始终会传入 options 对象,
|
// 注意:不能以 !onShowOptions 判断,onLaunch/onShow 始终会传入 options 对象,
|
||||||
@@ -113,14 +120,20 @@ export function captureAppLaunchData(onShowOptions) {
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
try {
|
try {
|
||||||
data = tryGetData(wx.getEnterOptionsSync?.() || {}, '当前进入(getEnterOptionsSync)')
|
data = tryGetData(wx.getEnterOptionsSync?.() || {}, '当前进入(getEnterOptionsSync)')
|
||||||
|
if (data) dataSource = 'enter'
|
||||||
} catch (e) { console.error('getEnterOptionsSync 失败:', e) }
|
} catch (e) { console.error('getEnterOptionsSync 失败:', e) }
|
||||||
}
|
}
|
||||||
if (!data) {
|
if (!data) {
|
||||||
try {
|
try {
|
||||||
data = tryGetData(wx.getLaunchOptionsSync?.() || {}, '冷启动(getLaunchOptionsSync)')
|
data = tryGetData(wx.getLaunchOptionsSync?.() || {}, '冷启动(getLaunchOptionsSync)')
|
||||||
|
if (data) dataSource = 'launch'
|
||||||
} catch (e) { console.error('getLaunchOptionsSync 失败:', e) }
|
} catch (e) { console.error('getLaunchOptionsSync 失败:', e) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getLaunchOptionsSync 返回的是首次冷启动的参数,热启动再次从 App 进入时仍是旧值。
|
||||||
|
// 用它恢复缴费参数会把上一次的金额/billIds 覆盖进来,因此只允许它恢复登录态。
|
||||||
|
const isStaleSource = dataSource === 'launch'
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
// 恢复登录态:只要 App 传入了 token/userId 就恢复,不依赖支付字段名
|
// 恢复登录态:只要 App 传入了 token/userId 就恢复,不依赖支付字段名
|
||||||
if (data.token) {
|
if (data.token) {
|
||||||
@@ -133,7 +146,10 @@ export function captureAppLaunchData(onShowOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 存在支付参数时才作为 App 支付进入处理
|
// 存在支付参数时才作为 App 支付进入处理
|
||||||
if (data.payAmount || data.acct || data.custId || data.billId || data.billIds) {
|
const hasPaymentParams = !!(data.payAmount || data.acct || data.custId || data.billId || data.billIds)
|
||||||
|
if (hasPaymentParams && isStaleSource) {
|
||||||
|
console.log('冷启动兜底参数为旧值,跳过缴费参数恢复')
|
||||||
|
} else if (hasPaymentParams) {
|
||||||
// 归一化 billId/billIds:单个 id 用 billId,多个用 billIds,统一转为 billIds 数组
|
// 归一化 billId/billIds:单个 id 用 billId,多个用 billIds,统一转为 billIds 数组
|
||||||
normalizeBillParams(data)
|
normalizeBillParams(data)
|
||||||
uni.setStorageSync(STORAGE_KEY, data)
|
uni.setStorageSync(STORAGE_KEY, data)
|
||||||
@@ -144,8 +160,9 @@ export function captureAppLaunchData(onShowOptions) {
|
|||||||
// 归一化 queryData 中的 billId/billIds
|
// 归一化 queryData 中的 billId/billIds
|
||||||
normalizeBillParams(queryData)
|
normalizeBillParams(queryData)
|
||||||
|
|
||||||
// 单独保存参数供接口使用(优先 queryData,fallback 到 data,即 extraData 来源)
|
// 单独保存参数供接口使用(优先 queryData,fallback 到 data,即 extraData 来源)。
|
||||||
const queryParams = queryData || data
|
// 冷启动兜底来源不写入,避免拿着上一次的账单去支付。
|
||||||
|
const queryParams = isStaleSource ? null : (queryData || data)
|
||||||
if (queryParams) {
|
if (queryParams) {
|
||||||
uni.setStorageSync(APP_QUERY_KEY, queryParams)
|
uni.setStorageSync(APP_QUERY_KEY, queryParams)
|
||||||
console.log('已存储 App 接口参数:', JSON.stringify(queryParams))
|
console.log('已存储 App 接口参数:', JSON.stringify(queryParams))
|
||||||
@@ -179,6 +196,23 @@ export function clearAppQueryParams() {
|
|||||||
uni.removeStorageSync(APP_QUERY_KEY)
|
uni.removeStorageSync(APP_QUERY_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理全部缴费缓存(App 传入参数 / 接口参数 / 页面条目 / 支付返回结果)
|
||||||
|
* 用于返回 App 前、以及再次从 App 进入时重置上一次的数据,
|
||||||
|
* 避免小程序热启动 onLoad 不执行导致继续展示上一次的金额。
|
||||||
|
*/
|
||||||
|
export function clearPaymentCache() {
|
||||||
|
uni.removeStorageSync(STORAGE_KEY)
|
||||||
|
uni.removeStorageSync(APP_QUERY_KEY)
|
||||||
|
uni.removeStorageSync(PAYMENT_RESULT_KEY)
|
||||||
|
uni.removeStorageSync(PAYMENT_ITEM_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 清除页面缓存的缴费条目 */
|
||||||
|
export function clearPaymentItem() {
|
||||||
|
uni.removeStorageSync(PAYMENT_ITEM_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
/** 组装 paymentItem */
|
/** 组装 paymentItem */
|
||||||
export function buildPaymentItemFromApp(appData) {
|
export function buildPaymentItemFromApp(appData) {
|
||||||
if (!appData) return null
|
if (!appData) return null
|
||||||
@@ -193,22 +227,31 @@ export function buildPaymentItemFromApp(appData) {
|
|||||||
* 本小程序在 App.onShow 中通过 referrerInfo.extraData 接收(场景值 1038)。
|
* 本小程序在 App.onShow 中通过 referrerInfo.extraData 接收(场景值 1038)。
|
||||||
* 这里只负责捕获/读取/清除原始返回数据,成功/失败判定见 resolvePaymentResult。
|
* 这里只负责捕获/读取/清除原始返回数据,成功/失败判定见 resolvePaymentResult。
|
||||||
*/
|
*/
|
||||||
const PAYMENT_RESULT_KEY = 'payment_return_result'
|
|
||||||
|
/**
|
||||||
|
* 判断 extraData 是否为 App 跳转参数(而非支付小程序返回)。
|
||||||
|
* App 跳转必然带登录凭证或缴费参数,支付返回只带支付结果字段。
|
||||||
|
*/
|
||||||
|
function isAppLaunchExtraData(extraData) {
|
||||||
|
if (!extraData || typeof extraData !== 'object') return false
|
||||||
|
return !!(extraData.token || extraData.userId || extraData.payAmount || extraData.acct ||
|
||||||
|
extraData.custId || extraData.billId || extraData.billIds)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 捕获支付返回结果(在 App.onShow 中调用)
|
* 捕获支付返回结果(在 App.onShow 中调用)
|
||||||
|
* 返回 true 表示本次进入是支付返回,调用方(App.vue)据此跳过 App 跳转参数捕获 ——
|
||||||
|
* 否则兜底参数会把上一次的账单写回缓存,缴费页会误判为「再次从 App 进入」并重置成待缴费状态。
|
||||||
* 注意:App 冷/热启动进入时 extraData 是支付参数(payAmount/billIds 等),
|
* 注意:App 冷/热启动进入时 extraData 是支付参数(payAmount/billIds 等),
|
||||||
* 并非支付返回,需跳过,避免覆盖真实结果。
|
* 并非支付返回,需跳过,避免覆盖真实结果。
|
||||||
*/
|
*/
|
||||||
export function capturePaymentResult(onShowOptions) {
|
export function capturePaymentResult(onShowOptions) {
|
||||||
if (!onShowOptions) return
|
if (!onShowOptions) return false
|
||||||
const extraData = onShowOptions?.referrerInfo?.extraData
|
const extraData = onShowOptions?.referrerInfo?.extraData
|
||||||
if (!extraData) return
|
if (!extraData) return false
|
||||||
|
|
||||||
// 含支付参数字段说明是 App 跳转进入(冷/热启动),不是支付返回,跳过
|
// 含登录凭证/缴费参数字段说明是 App 跳转进入(冷/热启动),不是支付返回
|
||||||
if (typeof extraData === 'object' && (extraData.payAmount || extraData.billId || extraData.billIds || extraData.acct || extraData.custId)) {
|
if (isAppLaunchExtraData(extraData)) return false
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let parsed = extraData
|
let parsed = extraData
|
||||||
if (typeof extraData === 'string') {
|
if (typeof extraData === 'string') {
|
||||||
@@ -218,8 +261,11 @@ export function capturePaymentResult(onShowOptions) {
|
|||||||
parsed = parseQueryString(extraData)
|
parsed = parseQueryString(extraData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isAppLaunchExtraData(parsed)) return false
|
||||||
|
|
||||||
console.log('捕获到支付返回结果:', JSON.stringify(parsed))
|
console.log('捕获到支付返回结果:', JSON.stringify(parsed))
|
||||||
uni.setStorageSync(PAYMENT_RESULT_KEY, parsed)
|
uni.setStorageSync(PAYMENT_RESULT_KEY, parsed)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 读取支付返回结果(读取后建议调用 clearPaymentReturnResult 清除) */
|
/** 读取支付返回结果(读取后建议调用 clearPaymentReturnResult 清除) */
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
let baseUrl = '';
|
let baseUrl = '';
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
// baseUrl = 'https://wuyeapi.ckdzkj.com'; // 开发环境
|
// baseUrl = 'https://wuyeapi.ckdzkj.com'; // 开发环境
|
||||||
// baseUrl = "http://192.168.1.222:8080"
|
baseUrl = "http://192.168.0.222:8080"
|
||||||
baseUrl = "https://apitest.ckdzkj.com";
|
// baseUrl = "https://wuyeapi.ckdzkj.com";
|
||||||
} else {
|
} else {
|
||||||
// baseUrl = 'https://wuyeapi.ckdzkj.com'; // 生产环境
|
baseUrl = 'https://wuyeapi.ckdzkj.com'; // 生产环境
|
||||||
baseUrl = "https://apitest.ckdzkj.com";
|
// baseUrl = "https://apitest.ckdzkj.com";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,13 +19,13 @@
|
|||||||
<button class="pay-btn" @click="handlePay">立即缴费</button>
|
<button class="pay-btn" @click="handlePay">立即缴费</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-section" v-if="currentStep === 2">
|
<view class="btn-section" v-if="currentStep === 2">
|
||||||
<button class="pay-btn" open-type="launchApp" app-parameter="payResult=success" @error="handleLaunchAppError">
|
<button class="pay-btn" open-type="launchApp" app-parameter="payResult=success" @click="handleBackToApp" @error="handleLaunchAppError">
|
||||||
返回
|
返回
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-section" v-if="currentStep === 3">
|
<view class="btn-section" v-if="currentStep === 3">
|
||||||
<!-- <button class="retry-btn" @click="handleRetry">重新缴费</button> -->
|
<!-- <button class="retry-btn" @click="handleRetry">重新缴费</button> -->
|
||||||
<button class="pay-btn" open-type="launchApp" app-parameter="payResult=fail" @error="handleLaunchAppError">
|
<button class="pay-btn" open-type="launchApp" app-parameter="payResult=fail" @click="handleBackToApp" @error="handleLaunchAppError">
|
||||||
返回
|
返回
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive } from 'vue'
|
import { ref, reactive } from 'vue'
|
||||||
import { onShow, onLoad } from '@dcloudio/uni-app'
|
import { onShow, onLoad } from '@dcloudio/uni-app'
|
||||||
import { getAppPaymentData, getAppQueryParams, clearAppPaymentData, buildPaymentItemFromApp, getPaymentReturnResult, clearPaymentReturnResult, resolvePaymentResult } from '/pageSubPack/api/appLaunch.js'
|
import { getAppPaymentData, getAppQueryParams, clearAppPaymentData, buildPaymentItemFromApp, getPaymentReturnResult, clearPaymentReturnResult, resolvePaymentResult, clearPaymentItem, clearPaymentCache } from '/pageSubPack/api/appLaunch.js'
|
||||||
import { getBankMiniProgramParams } from '/pageSubPack/api/apiSub.js'
|
import { getBankMiniProgramParams } from '/pageSubPack/api/apiSub.js'
|
||||||
import { showApiError } from '/pageSubPack/api/request.js'
|
import { showApiError } from '/pageSubPack/api/request.js'
|
||||||
|
|
||||||
@@ -44,31 +44,54 @@ const currentStep = ref(1)
|
|||||||
const navigatedToPayment = ref(false)
|
const navigatedToPayment = ref(false)
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
const data = loadPaymentItem()
|
loadPaymentItem()
|
||||||
Object.assign(paymentItem, data)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
// 从日照银行支付小程序返回后,根据返回结果显示成功/失败页
|
// 从日照银行支付小程序返回后,根据返回结果显示成功/失败页。
|
||||||
|
// 必须放在最前面判断:本页发起过支付跳转(navigatedToPayment)时,缓存里可能
|
||||||
|
// 残留兜底写入的 App 参数,若先走下面的 App 入口分支会被重置回待缴费状态,
|
||||||
|
// 成功/失败页就永远不显示了。
|
||||||
if (navigatedToPayment.value) {
|
if (navigatedToPayment.value) {
|
||||||
navigatedToPayment.value = false
|
navigatedToPayment.value = false
|
||||||
const result = resolvePaymentResult(getPaymentReturnResult())
|
const result = resolvePaymentResult(getPaymentReturnResult())
|
||||||
clearPaymentReturnResult()
|
clearPaymentReturnResult()
|
||||||
|
clearAppPaymentData()
|
||||||
currentStep.value = result === 'success' ? 2 : 3
|
currentStep.value = result === 'success' ? 2 : 3
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 再次从 App 跳转进入(携带新的缴费参数):小程序热启动时 onLoad 不会重复执行,
|
||||||
|
// 页面会残留上一次的金额/状态,这里必须重置后重新加载。
|
||||||
|
if (getAppPaymentData()) {
|
||||||
|
resetPaymentState()
|
||||||
|
loadPaymentItem()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/** 重置为待缴费状态,并清掉上一次缴费残留的页面状态与缓存条目 */
|
||||||
|
const resetPaymentState = () => {
|
||||||
|
navigatedToPayment.value = false
|
||||||
|
currentStep.value = 1
|
||||||
|
clearPaymentReturnResult()
|
||||||
|
clearPaymentItem()
|
||||||
|
Object.keys(paymentItem).forEach(key => delete paymentItem[key])
|
||||||
|
}
|
||||||
|
|
||||||
const loadPaymentItem = () => {
|
const loadPaymentItem = () => {
|
||||||
|
Object.keys(paymentItem).forEach(key => delete paymentItem[key])
|
||||||
const appData = getAppPaymentData()
|
const appData = getAppPaymentData()
|
||||||
if (appData) {
|
if (appData) {
|
||||||
console.log('-----检测到 App 跳转参数:', appData)
|
console.log('-----检测到 App 跳转参数:', appData)
|
||||||
clearAppPaymentData()
|
clearAppPaymentData()
|
||||||
const item = buildPaymentItemFromApp(appData)
|
const item = buildPaymentItemFromApp(appData)
|
||||||
uni.setStorageSync('arrearsPayment', item)
|
uni.setStorageSync('arrearsPayment', item)
|
||||||
|
Object.assign(paymentItem, item)
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
const stored = uni.getStorageSync('arrearsPayment')
|
const stored = uni.getStorageSync('arrearsPayment')
|
||||||
return (typeof stored === 'object' && stored !== null) ? stored : {}
|
const data = (typeof stored === 'object' && stored !== null) ? stored : {}
|
||||||
|
Object.assign(paymentItem, data)
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePay = async () => {
|
const handlePay = async () => {
|
||||||
@@ -111,6 +134,12 @@ const handlePay = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 返回 App 前清掉本次缴费缓存,下次从 App 进入时不会残留上一次的金额 */
|
||||||
|
const handleBackToApp = () => {
|
||||||
|
navigatedToPayment.value = false
|
||||||
|
clearPaymentCache()
|
||||||
|
}
|
||||||
|
|
||||||
const handleLaunchAppError = () => {
|
const handleLaunchAppError = () => {
|
||||||
uni.showToast({ title: '请点击左上角关闭返回', icon: 'none', duration: 2000 })
|
uni.showToast({ title: '请点击左上角关闭返回', icon: 'none', duration: 2000 })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user