fix: 首次点击确认支付无反应——upsdk 异步注入未就绪即唤起,改为就绪 Promise 等待(9s超时)后再 pluginReady;容器判定去 SDK 依赖只认 UA
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
d39e30925d
commit
be4aafa6fd
@@ -22,12 +22,11 @@ export const VOUCHER_USE_FLOW = [
|
|||||||
'支付差额可选:油卡 / 现金等'
|
'支付差额可选:油卡 / 现金等'
|
||||||
]
|
]
|
||||||
|
|
||||||
// xuchao: 云闪付容器判定。UA 特征 + window.upsdk 双判,真机实测后定稿(方案文档 §8 挂账项);
|
// xuchao: 云闪付容器判定只看 UA——不能掺 window.upsdk 是否已加载(SDK 是异步注入的,
|
||||||
// 若实测 UA 关键字不符,只需调整下方正则。
|
// 首屏点击时可能还没 load 完,会把云闪付内首点误判为站外)。UA 关键字真机实测后定稿。
|
||||||
export function isUnionPayApp() {
|
export function isUnionPayApp() {
|
||||||
if (typeof navigator === 'undefined' || !navigator.userAgent) return false
|
if (typeof navigator === 'undefined' || !navigator.userAgent) return false
|
||||||
if (!/unionpay|upsdk|云闪付/i.test(navigator.userAgent)) return false
|
return /unionpay|upsdk|云闪付/i.test(navigator.userAgent)
|
||||||
return typeof window !== 'undefined' && !!window.upsdk
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// xuchao: open-api/hhService/voucher/* 为双层壳:外层 errcode,内层 data.code 才是业务码
|
// xuchao: open-api/hhService/voucher/* 为双层壳:外层 errcode,内层 data.code 才是业务码
|
||||||
|
|||||||
@@ -86,16 +86,25 @@ export default {
|
|||||||
this.initFromServer()
|
this.initFromServer()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// xuchao: upsdk 运行时注入。不能依赖 index.html 静态标签——HBuilderX 命令行构建的 H5 模板
|
// xuchao: upsdk 运行时注入并返回就绪 Promise(同一加载只发起一次;超时/失败 resolve(false))。
|
||||||
// 不受项目根 index.html 控制(产物会丢标签),与人脸 SDK 同款动态加载兜底。
|
// 不能依赖 index.html 静态标签——HBuilderX 命令行构建的 H5 模板不吃根 index.html(会丢标签)。
|
||||||
loadUpSdk() {
|
loadUpSdk(timeout = 9000) {
|
||||||
if (typeof window !== 'undefined' && window.upsdk) return
|
if (typeof window === 'undefined' || typeof document === 'undefined') return Promise.resolve(false)
|
||||||
if (typeof document === 'undefined') return
|
if (window.upsdk) return Promise.resolve(true)
|
||||||
if (document.querySelector('script[data-upsdk]')) return
|
if (this._upSdkPromise) return this._upSdkPromise
|
||||||
const s = document.createElement('script')
|
const loading = new Promise(resolve => {
|
||||||
s.src = 'https://open.95516.com/s/open/js/upsdk.js'
|
let done = false
|
||||||
s.setAttribute('data-upsdk', '1')
|
const finish = v => { if (!done) { done = true; resolve(v) } }
|
||||||
document.head.appendChild(s)
|
const s = document.createElement('script')
|
||||||
|
s.src = 'https://open.95516.com/s/open/js/upsdk.js'
|
||||||
|
s.setAttribute('data-upsdk', '1')
|
||||||
|
s.onload = () => finish(!!window.upsdk)
|
||||||
|
s.onerror = () => finish(false)
|
||||||
|
document.head.appendChild(s)
|
||||||
|
setTimeout(() => finish(!!window.upsdk), timeout)
|
||||||
|
})
|
||||||
|
this._upSdkPromise = loading
|
||||||
|
return loading
|
||||||
},
|
},
|
||||||
// xuchao: 价格展示以服务端 latest 为准(测试期 0.01);已有待支付单自动续用;已发券直接跳券详情
|
// xuchao: 价格展示以服务端 latest 为准(测试期 0.01);已有待支付单自动续用;已发券直接跳券详情
|
||||||
initFromServer() {
|
initFromServer() {
|
||||||
@@ -143,33 +152,29 @@ export default {
|
|||||||
uni.showToast({ title: (err && err.message) || '操作失败,请稍后再试', icon: 'none' })
|
uni.showToast({ title: (err && err.message) || '操作失败,请稍后再试', icon: 'none' })
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
// xuchao: 云闪付控件唤起,交互与湘工惠商城一致(xghmall ordersure.vue:195-229 同型)
|
// xuchao: 云闪付控件唤起。先等 SDK 就绪(修复首点无反应:脚本异步加载未完成时
|
||||||
launchUnionPay(tn) {
|
// 旧逻辑只重试 4 秒且静默;就绪判定收敛到 loadUpSdk 的 Promise)。
|
||||||
this.loadUpSdk()
|
async launchUnionPay(tn) {
|
||||||
const tryPay = (retries) => {
|
const ready = await this.loadUpSdk()
|
||||||
if (typeof window !== 'undefined' && window.upsdk) {
|
if (!ready) {
|
||||||
window.upsdk.pluginReady(() => {
|
this.submitting = false
|
||||||
window.upsdk.pay({
|
uni.showToast({ title: '支付组件加载失败,请稍后重试', icon: 'none' })
|
||||||
tn: tn,
|
return
|
||||||
success: () => {
|
|
||||||
uni.redirectTo({ url: '/pages/petrol/voucherDetail?orderNo=' + this.orderNo })
|
|
||||||
},
|
|
||||||
fail: () => {
|
|
||||||
this.submitting = false
|
|
||||||
uni.showToast({ title: '支付未完成,可在门店页继续支付', icon: 'none' })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
// 控件无异步结果时兜底:3 秒后恢复按钮(支付成功路径以回跳/轮询为准)
|
|
||||||
setTimeout(() => { this.submitting = false }, 3000)
|
|
||||||
} else if (retries > 0) {
|
|
||||||
setTimeout(() => tryPay(retries - 1), 500)
|
|
||||||
} else {
|
|
||||||
this.submitting = false
|
|
||||||
uni.showToast({ title: '支付组件加载失败,请在云闪付内重进页面', icon: 'none' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tryPay(8) // SDK 注入后最多等 4 秒
|
window.upsdk.pluginReady(() => {
|
||||||
|
window.upsdk.pay({
|
||||||
|
tn: tn,
|
||||||
|
success: () => {
|
||||||
|
uni.redirectTo({ url: '/pages/petrol/voucherDetail?orderNo=' + this.orderNo })
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
this.submitting = false
|
||||||
|
uni.showToast({ title: '支付未完成,可在门店页继续支付', icon: 'none' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// 控件无异步结果时兜底:3 秒后恢复按钮(支付成功路径以回跳/轮询为准)
|
||||||
|
setTimeout(() => { this.submitting = false }, 3000)
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
const pages = getCurrentPages()
|
const pages = getCurrentPages()
|
||||||
|
|||||||
Reference in New Issue
Block a user