新增支付失败逻辑
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { onLaunch, onShow } from '@dcloudio/uni-app'
|
import { onLaunch, onShow } from '@dcloudio/uni-app'
|
||||||
import { captureAppLaunchData } from '/pageSubPack/api/appLaunch.js'
|
import { captureAppLaunchData, capturePaymentResult } from '/pageSubPack/api/appLaunch.js'
|
||||||
|
|
||||||
onLaunch((options) => {
|
onLaunch((options) => {
|
||||||
console.log('App 启动', JSON.stringify(options))
|
console.log('App 启动', JSON.stringify(options))
|
||||||
@@ -16,6 +16,8 @@
|
|||||||
console.log('App onShow, options:', JSON.stringify(options))
|
console.log('App onShow, options:', JSON.stringify(options))
|
||||||
// 捕获 App 跳转传入的支付参数(热启动 — options 携带新的 referrerInfo)
|
// 捕获 App 跳转传入的支付参数(热启动 — options 携带新的 referrerInfo)
|
||||||
captureAppLaunchData(options)
|
captureAppLaunchData(options)
|
||||||
|
// 捕获日照银行支付小程序返回的支付结果(navigateBackMiniProgram 的 extraData)
|
||||||
|
capturePaymentResult(options)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 获取 uniPush 2.0 CID
|
// 获取 uniPush 2.0 CID
|
||||||
|
|||||||
@@ -175,3 +175,71 @@ export function buildPaymentItemFromApp(appData) {
|
|||||||
const displayName = appData.goodName || appData.remark || appData.type || '缴费'
|
const displayName = appData.goodName || appData.remark || appData.type || '缴费'
|
||||||
return { ...appData, type: displayName, rechargeAmount: amount }
|
return { ...appData, type: displayName, rechargeAmount: amount }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付返回结果
|
||||||
|
* 日照银行支付小程序完成支付后,通过 navigateBackMiniProgram 携带 extraData 返回,
|
||||||
|
* 本小程序在 App.onShow 中通过 referrerInfo.extraData 接收(场景值 1038)。
|
||||||
|
* 这里只负责捕获/读取/清除原始返回数据,成功/失败判定见 resolvePaymentResult。
|
||||||
|
*/
|
||||||
|
const PAYMENT_RESULT_KEY = 'payment_return_result'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 捕获支付返回结果(在 App.onShow 中调用)
|
||||||
|
* 注意:App 冷/热启动进入时 extraData 是支付参数(payAmount/billIds 等),
|
||||||
|
* 并非支付返回,需跳过,避免覆盖真实结果。
|
||||||
|
*/
|
||||||
|
export function capturePaymentResult(onShowOptions) {
|
||||||
|
if (!onShowOptions) return
|
||||||
|
const extraData = onShowOptions?.referrerInfo?.extraData
|
||||||
|
if (!extraData) return
|
||||||
|
|
||||||
|
// 含支付参数字段说明是 App 跳转进入(冷/热启动),不是支付返回,跳过
|
||||||
|
if (typeof extraData === 'object' && (extraData.payAmount || extraData.billId || extraData.billIds || extraData.acct || extraData.custId)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let parsed = extraData
|
||||||
|
if (typeof extraData === 'string') {
|
||||||
|
try {
|
||||||
|
parsed = JSON.parse(extraData)
|
||||||
|
} catch (e) {
|
||||||
|
parsed = parseQueryString(extraData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log('捕获到支付返回结果:', JSON.stringify(parsed))
|
||||||
|
uni.setStorageSync(PAYMENT_RESULT_KEY, parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 读取支付返回结果(读取后建议调用 clearPaymentReturnResult 清除) */
|
||||||
|
export function getPaymentReturnResult() {
|
||||||
|
try { return uni.getStorageSync(PAYMENT_RESULT_KEY) || null } catch (e) { return null }
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 清除支付返回结果 */
|
||||||
|
export function clearPaymentReturnResult() {
|
||||||
|
uni.removeStorageSync(PAYMENT_RESULT_KEY)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 失败/成功信号值(大小写不敏感),字段名与取值以日照银行实际返回为准,如不一致只需调整下方映射
|
||||||
|
const FAIL_SIGNALS = ['fail', 'failed', 'cancel', 'cancelled', 'error', 'closed', 'notpay', 'payerror', '2', 'false', 'no']
|
||||||
|
const SUCCESS_SIGNALS = ['success', 'ok', 'paid', 'finish', 'finished', '1', '0000', '0', '200', 'true', 'yes']
|
||||||
|
const RESULT_FIELDS = ['payResult', 'result', 'status', 'payStatus', 'tradeState', 'returnCode', 'code', 'errCode']
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判定日照银行返回的支付结果:'success' | 'fail' | null(无法判定)
|
||||||
|
*/
|
||||||
|
export function resolvePaymentResult(data) {
|
||||||
|
if (!data || typeof data !== 'object') return null
|
||||||
|
// 布尔字段优先
|
||||||
|
if (typeof data.success === 'boolean') return data.success ? 'success' : 'fail'
|
||||||
|
if (typeof data.isSuccess === 'boolean') return data.isSuccess ? 'success' : 'fail'
|
||||||
|
for (const key of RESULT_FIELDS) {
|
||||||
|
const v = data[key]
|
||||||
|
if (v === undefined || v === null || v === '') continue
|
||||||
|
const s = String(v).trim().toLowerCase()
|
||||||
|
if (FAIL_SIGNALS.includes(s)) return 'fail'
|
||||||
|
if (SUCCESS_SIGNALS.includes(s)) return 'success'
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,11 @@
|
|||||||
<view class="title">缴费成功</view>
|
<view class="title">缴费成功</view>
|
||||||
<view class="desc">成功缴纳{{ paymentItem.type || '' }}费用</view>
|
<view class="desc">成功缴纳{{ paymentItem.type || '' }}费用</view>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="container" v-if="currentStep === 3">
|
||||||
|
<view class="fail-icon"><text class="icon-fail">✕</text></view>
|
||||||
|
<view class="title">缴费失败</view>
|
||||||
|
<view class="desc">未能完成缴费,请重新尝试</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
@@ -18,13 +23,19 @@
|
|||||||
返回
|
返回
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="btn-section" v-if="currentStep === 3">
|
||||||
|
<!-- <button class="retry-btn" @click="handleRetry">重新缴费</button> -->
|
||||||
|
<button class="pay-btn" open-type="launchApp" app-parameter="payResult=fail" @error="handleLaunchAppError">
|
||||||
|
返回
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<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 } from '/pageSubPack/api/appLaunch.js'
|
import { getAppPaymentData, getAppQueryParams, clearAppPaymentData, buildPaymentItemFromApp, getPaymentReturnResult, clearPaymentReturnResult, resolvePaymentResult } 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'
|
||||||
|
|
||||||
@@ -38,10 +49,12 @@ onLoad(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
// 从日照银行支付小程序返回后,显示支付成功页
|
// 从日照银行支付小程序返回后,根据返回结果显示成功/失败页
|
||||||
if (navigatedToPayment.value) {
|
if (navigatedToPayment.value) {
|
||||||
navigatedToPayment.value = false
|
navigatedToPayment.value = false
|
||||||
currentStep.value = 2
|
const result = resolvePaymentResult(getPaymentReturnResult())
|
||||||
|
clearPaymentReturnResult()
|
||||||
|
currentStep.value = result === 'fail' ? 3 : 2
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -76,6 +89,7 @@ const handlePay = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
navigatedToPayment.value = true
|
navigatedToPayment.value = true
|
||||||
|
clearPaymentReturnResult()
|
||||||
wx.navigateToMiniProgram({
|
wx.navigateToMiniProgram({
|
||||||
appId: 'wxc0189436c58b59cd',
|
appId: 'wxc0189436c58b59cd',
|
||||||
path: 'pages/pay/pay',
|
path: 'pages/pay/pay',
|
||||||
@@ -100,6 +114,10 @@ const handlePay = async () => {
|
|||||||
const handleLaunchAppError = () => {
|
const handleLaunchAppError = () => {
|
||||||
uni.showToast({ title: '请点击左上角关闭返回', icon: 'none', duration: 2000 })
|
uni.showToast({ title: '请点击左上角关闭返回', icon: 'none', duration: 2000 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const handleRetry = () => {
|
||||||
|
// currentStep.value = 1
|
||||||
|
// }
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -114,6 +132,9 @@ page { background-color: #f9f9f9; }
|
|||||||
.container { display: flex; flex-direction: column; align-items: center; }
|
.container { display: flex; flex-direction: column; align-items: center; }
|
||||||
.success-icon { width: 220rpx; height: 220rpx; border-radius: 50%; background-color: #1677ff; display: flex; align-items: center; justify-content: center; margin-top: 200rpx; margin-bottom: 60rpx; }
|
.success-icon { width: 220rpx; height: 220rpx; border-radius: 50%; background-color: #1677ff; display: flex; align-items: center; justify-content: center; margin-top: 200rpx; margin-bottom: 60rpx; }
|
||||||
.icon-check { color: #fff; font-size: 130rpx; font-weight: bold; }
|
.icon-check { color: #fff; font-size: 130rpx; font-weight: bold; }
|
||||||
|
.fail-icon { width: 220rpx; height: 220rpx; border-radius: 50%; background-color: #fa5151; display: flex; align-items: center; justify-content: center; margin-top: 200rpx; margin-bottom: 60rpx; }
|
||||||
|
.icon-fail { color: #fff; font-size: 130rpx; font-weight: bold; }
|
||||||
|
.retry-btn { width: 100%; height: 100rpx; line-height: 100rpx; background-color: #fff; color: #007aff; border: 2rpx solid #007aff; border-radius: 16rpx; font-size: 32rpx; margin-bottom: 20rpx; }
|
||||||
.title { font-size: 40rpx; font-weight: bold; color: #000; margin-bottom: 20rpx; }
|
.title { font-size: 40rpx; font-weight: bold; color: #000; margin-bottom: 20rpx; }
|
||||||
.desc { font-size: 32rpx; color: #666; text-align: center; margin-bottom: 150rpx; }
|
.desc { font-size: 32rpx; color: #666; text-align: center; margin-bottom: 150rpx; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="home">
|
<view class="home">
|
||||||
<!-- 顶部品牌区 -->
|
<!-- 顶部品牌区 -->
|
||||||
<view class="header">
|
<view class="header" @click="gotoPayment">
|
||||||
<view class="app-name">花开物业</view>
|
<view class="app-name">花开物业</view>
|
||||||
<view class="app-slogan">物业缴费服务</view>
|
<view class="app-slogan">物业缴费服务</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -65,6 +65,9 @@ onShow(() => {
|
|||||||
loadRecords()
|
loadRecords()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// const gotoPayment =()=>{
|
||||||
|
// uni.navigateTo({ url: '/pages/arrearsPayment/arrearsPayment' })
|
||||||
|
// }
|
||||||
|
|
||||||
const goLogin = () => {
|
const goLogin = () => {
|
||||||
uni.navigateTo({ url: '/pageSubPack/loginSub/pwd-login' })
|
uni.navigateTo({ url: '/pageSubPack/loginSub/pwd-login' })
|
||||||
|
|||||||
Reference in New Issue
Block a user