Files
2026-09-21 10:31:57 +08:00

170 lines
6.6 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="contentStyle">
<scroll-view class="page" scroll-y="true">
<view class="container">
<view v-if="currentStep === 2" class="container">
<view class="success-icon"><text class="icon-check">✓</text></view>
<view class="title">缴费成功</view>
<view class="desc">成功缴纳{{ paymentItem.type || '' }}费用</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>
</scroll-view>
<view class="btn-section" v-if="currentStep === 1">
<button class="pay-btn" @click="handlePay">立即缴费</button>
</view>
<view class="btn-section" v-if="currentStep === 2">
<button class="pay-btn" open-type="launchApp" app-parameter="payResult=success" @click="handleBackToApp" @error="handleLaunchAppError">
返回
</button>
</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" @click="handleBackToApp" @error="handleLaunchAppError">
返回
</button>
</view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { onShow, onLoad } from '@dcloudio/uni-app'
import { getAppPaymentData, getAppQueryParams, clearAppPaymentData, buildPaymentItemFromApp, getPaymentReturnResult, clearPaymentReturnResult, resolvePaymentResult, clearPaymentItem, clearPaymentCache } from '/pageSubPack/api/appLaunch.js'
import { getBankMiniProgramParams } from '/pageSubPack/api/apiSub.js'
import { showApiError } from '/pageSubPack/api/request.js'
const paymentItem = reactive({})
const currentStep = ref(1)
const navigatedToPayment = ref(false)
onLoad(() => {
loadPaymentItem()
})
onShow(() => {
// 从日照银行支付小程序返回后,根据返回结果显示成功/失败页。
// 必须放在最前面判断:本页发起过支付跳转(navigatedToPayment)时,缓存里可能
// 残留兜底写入的 App 参数,若先走下面的 App 入口分支会被重置回待缴费状态,
// 成功/失败页就永远不显示了。
if (navigatedToPayment.value) {
navigatedToPayment.value = false
const result = resolvePaymentResult(getPaymentReturnResult())
clearPaymentReturnResult()
clearAppPaymentData()
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 = () => {
Object.keys(paymentItem).forEach(key => delete paymentItem[key])
const appData = getAppPaymentData()
if (appData) {
console.log('-----检测到 App 跳转参数:', appData)
clearAppPaymentData()
const item = buildPaymentItemFromApp(appData)
uni.setStorageSync('arrearsPayment', item)
Object.assign(paymentItem, item)
return item
}
const stored = uni.getStorageSync('arrearsPayment')
const data = (typeof stored === 'object' && stored !== null) ? stored : {}
Object.assign(paymentItem, data)
return data
}
const handlePay = async () => {
const apiParams = getAppQueryParams()
if (!apiParams) {
uni.showToast({ title: '支付参数缺失', icon: 'none' })
return
}
delete apiParams.token
delete apiParams.billId // billId 已归一化为 billIds 数组,删除冗余字段
console.log('-----传递小程序参数2222------:', apiParams)
uni.showLoading({ title: '加载中...', mask: true })
try {
const res = await getBankMiniProgramParams(apiParams)
uni.hideLoading()
if (res.code !== 200 || !res.data) {
uni.showToast({ title: res.msg || '获取支付参数失败', icon: 'none' })
return
}
navigatedToPayment.value = true
clearPaymentReturnResult()
wx.navigateToMiniProgram({
appId: 'wxc0189436c58b59cd',
path: 'pages/pay/pay',
extraData: res.data.extraData,
envVersion: 'trial',
success: () => {
console.log('已跳转到日照银行支付小程序')
},
fail: (err) => {
navigatedToPayment.value = false
console.error('跳转日照银行支付失败', err)
uni.showToast({ title: '拉起支付失败', icon: 'none' })
}
})
} catch (err) {
uni.hideLoading()
showApiError(err)
console.error('支付失败:', err)
}
}
/** 返回 App 前清掉本次缴费缓存,下次从 App 进入时不会残留上一次的金额 */
const handleBackToApp = () => {
navigatedToPayment.value = false
clearPaymentCache()
}
const handleLaunchAppError = () => {
uni.showToast({ title: '请点击左上角关闭返回', icon: 'none', duration: 2000 })
}
// const handleRetry = () => {
// currentStep.value = 1
// }
</script>
<style lang="scss">
page { background-color: #f9f9f9; }
</style>
<style scoped>
.contentStyle { display: flex; flex-direction: column; height: 100vh; background-color: #f9f9f9; }
.page { flex: 1; overflow-y: auto; padding: 0 40rpx; box-sizing: border-box; }
.btn-section { padding: 20rpx 30rpx 40rpx; }
.pay-btn { width: 100%; height: 100rpx; line-height: 100rpx; background-color: #007aff; color: #fff; border-radius: 16rpx; font-size: 32rpx; border: none; }
.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; }
.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; }
.desc { font-size: 32rpx; color: #666; text-align: center; margin-bottom: 150rpx; }
</style>