hejianhao
2026-08-21 5c0c0e7ddf66ea6223ad8ba775ee8bac3219465f
fix0806: 对接支付
2个文件已修改
70 ■■■■■ 已修改文件
traditionalApp/pages/webview/webview.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traditionalApp/utils/weizan-pay-bridge.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
traditionalApp/pages/webview/webview.vue
@@ -13,8 +13,13 @@
import { clearWebViewData } from '@/utils/webview-cache.js'
import { registerWeizanPayBridge, unregisterWeizanPayBridge } from '@/utils/weizan-pay-bridge.js'
// 微信开放平台 appId(见 manifest.json app-plus.distribute.sdkConfigs.share.weixin)
const WEIXIN_APP_ID = 'wx074c1f0cf5a0ecf4'
const webViewUrl = ref('')
let currentWebviewInstance: any = null
// 进入微赞直播页前记录原始 UA,退出时还原,避免全局 UA 常驻影响其它 webview
let originalUserAgent = ''
/**
 * 页面加载时读取外链地址与标题,并在加载 URL 前清理一次缓存避免上次登录态残留。
@@ -30,6 +35,9 @@
    if (shouldClearCache) {
        clearWebViewData()
        console.log('[WebView] 进入前缓存已清理,URL:', resolvedUrl)
        // 仅微赞直播间入口注入带 webchatPay/{appId} 的 UA,微赞 H5 靠它开启唤起支付逻辑。
        // 必须在给 web-view 赋值 URL(触发渲染)之前设置,底层 WebView 创建时才会带上该 UA。
        injectWeizanUserAgent()
    }
    // #endif
@@ -62,9 +70,57 @@
    if (currentWebviewInstance) {
        unregisterWeizanPayBridge(currentWebviewInstance)
    }
    // #ifdef APP-PLUS
    // 还原全局 UA,避免影响之后创建的其它 webview
    restoreUserAgent()
    // #endif
})
/**
 * 注入带 webchatPay/{appId} 的全局 UA(方式 B)。
 * 微赞 H5 通过 UA 中的 webchatPay 标识判断当前处于可唤起小程序支付的 APP 环境。
 * 用全局 setUserAgent 是因为通用 <web-view> 组件无法单独设置 UA;副作用由 onUnload 还原兜住。
 */
function injectWeizanUserAgent() {
    // #ifdef APP-PLUS
    try {
        const baseUA = plus.navigator.getUserAgent() || ''
        // 已包含标识则不重复追加,避免多次进入叠加
        if (baseUA.indexOf('webchatPay/') >= 0) {
            originalUserAgent = baseUA.replace(/\s*webchatPay\/\S+/g, '')
            console.log('[WebView] UA 已含 webchatPay,跳过追加。当前 UA:', baseUA)
            return
        }
        originalUserAgent = baseUA
        const nextUA = `${baseUA} webchatPay/${WEIXIN_APP_ID}`.trim()
        // 第二参 false:不持久化,仅本次运行期生效
        plus.navigator.setUserAgent(nextUA, false)
        console.log('[WebView] 已注入微赞支付 UA:', nextUA)
    } catch (e) {
        console.error('[WebView] 注入 UA 失败:', e)
    }
    // #endif
}
/**
 * 还原进入直播页前的原始 UA。
 */
function restoreUserAgent() {
    // #ifdef APP-PLUS
    try {
        if (!originalUserAgent) {
            return
        }
        plus.navigator.setUserAgent(originalUserAgent, false)
        console.log('[WebView] 已还原原始 UA:', originalUserAgent)
        originalUserAgent = ''
    } catch (e) {
        console.error('[WebView] 还原 UA 失败:', e)
    }
    // #endif
}
/**
 * 解码路由参数,异常时回退为空字符串。
 */
function decodeQueryValue(value: unknown) {
traditionalApp/utils/weizan-pay-bridge.js
@@ -73,11 +73,15 @@
 */
export function jumpToMiniProgramPay(params) {
    // #ifdef APP-PLUS
    console.log('[weizanPay] >>> jumpToMiniProgramPay 被调用, 原始入参:', params, '类型:', typeof params)
    const safeParams = normalizePayParams(params)
    console.log('[weizanPay] 归一化后参数:', JSON.stringify(safeParams))
    if (!safeParams.username) {
        console.warn('[weizanPay] username 缺失,终止唤起。safeParams=', JSON.stringify(safeParams))
        uni.showToast({ title: '支付参数缺失', icon: 'none' })
        return
    }
    console.log('[weizanPay] 参数校验通过,开始调用 plus.share.getServices 唤起小程序')
    plus.share.getServices((services) => {
        const wx = services && services.find((s) => s && s.id === 'weixin')
        if (!wx) {
@@ -114,8 +118,11 @@
    try {
        const JsInterface = plus.android.implements('io.dcloud.js.WeizanPayJsInterface', {
            [PAY_BRIDGE_NAME]: function (paramsJson) {
                // 注意:此日志运行在原生子线程
                console.log('[weizanPay][Android] JS 接口被触发, 收到原始字符串:', paramsJson)
                // JS 接口回调在原生子线程,必须切回 UI 线程才能拉起微信 SDK
                plus.android.runOnUiThread(() => {
                    console.log('[weizanPay][Android] 已切回 UI 线程, 开始解析参数')
                    const params = normalizePayParams(parseJsonSafe(paramsJson))
                    if (typeof onPay === 'function') {
                        try { onPay(params) } catch (e) {}
@@ -137,17 +144,22 @@
        // 实现 WKScriptMessageHandler 协议
        const MessageHandler = plus.ios.implements('NSObject<WKScriptMessageHandler>', {
            'userContentController:didReceiveScriptMessage:': function (controller, message) {
                console.log('[weizanPay][iOS] messageHandler 被触发, message=', message)
                if (!message) {
                    console.warn('[weizanPay][iOS] message 为空,终止')
                    return
                }
                // message.name === 'jumpToMiniProgramPay',message.body 是 H5 传的参数
                let raw = message
                try {
                    const body = plus.ios.invoke(message, 'body')
                    console.log('[weizanPay][iOS] message.body=', body, '类型:', typeof body)
                    if (body !== undefined && body !== null) {
                        raw = body
                    }
                } catch (e) {}
                } catch (e) {
                    console.error('[weizanPay][iOS] 取 message.body 失败:', e)
                }
                const params = normalizePayParams(parseJsonSafe(raw))
                if (typeof onPay === 'function') {
                    try { onPay(params) } catch (e) {}