修复讲解列表返回分流
Some checks failed
CI / verify (push) Has been cancelled

This commit is contained in:
lyf
2026-07-25 02:28:38 +08:00
parent 5d73848739
commit d94d689b40
5 changed files with 140 additions and 48 deletions

View File

@@ -8,6 +8,7 @@ import {
interface MiniProgramBridge {
getEnv?: (callback: (result: { miniprogram?: boolean }) => void) => void
navigateTo?: (options: { url: string; success?: () => void; fail?: (error: { errMsg?: string }) => void }) => void
navigateBack?: (options: { delta?: number; success?: () => void; fail?: (error: { errMsg?: string }) => void }) => void
}
export type WechatMiniProgramBridgeResult =
@@ -15,6 +16,11 @@ export type WechatMiniProgramBridgeResult =
| { status: 'not-embedded' }
| { status: 'failed'; reason: 'invalid-target' | 'bridge-unavailable' | 'not-in-mini-program' | 'navigation-failed' | 'page-not-found' | 'timeout' }
export type WechatMiniProgramReturnResult =
| { status: 'returned' }
| { status: 'not-embedded' }
| { status: 'failed'; reason: 'bridge-unavailable' | 'not-in-mini-program' | 'navigation-failed' | 'timeout' }
const SDK_URL = 'https://res.wx.qq.com/open/js/jweixin-1.3.2.js'
const BRIDGE_WAIT_TIMEOUT = 2500
const BRIDGE_POLL_INTERVAL = 50
@@ -22,6 +28,7 @@ const GET_ENV_TIMEOUT = 1500
const NAVIGATION_TIMEOUT = 3000
let pendingNavigation: Promise<WechatMiniProgramBridgeResult> | null = null
let pendingReturn: Promise<WechatMiniProgramReturnResult> | null = null
let sdkLoadPromise: Promise<void> | null = null
const getBridge = (): MiniProgramBridge | null => {
@@ -108,6 +115,31 @@ const navigateToHostLocationPage = (bridge: MiniProgramBridge, target: WechatOpe
}
})
const navigateBackToHostPage = (bridge: MiniProgramBridge) => new Promise<WechatMiniProgramReturnResult>((resolve) => {
if (!bridge.navigateBack) return resolve({ status: 'failed', reason: 'bridge-unavailable' })
let settled = false
const finish = (result: WechatMiniProgramReturnResult) => {
if (settled) return
settled = true
clearTimeout(timeout)
resolve(result)
}
const timeout = setTimeout(() => finish({ status: 'failed', reason: 'timeout' }), NAVIGATION_TIMEOUT)
try {
bridge.navigateBack({
delta: 1,
success: () => finish({ status: 'returned' }),
fail: (error) => {
console.error('返回微信小程序失败:', error)
finish({ status: 'failed', reason: 'navigation-failed' })
}
})
} catch (error) {
console.error('调用微信小程序返回桥接失败:', error)
finish({ status: 'failed', reason: 'navigation-failed' })
}
})
const openOnce = async (target: WechatOpenLocationTarget): Promise<WechatMiniProgramBridgeResult> => {
const validation = validateWechatOpenLocationTarget(target)
if (!validation.ok) return { status: 'failed', reason: 'invalid-target' }
@@ -118,8 +150,22 @@ const openOnce = async (target: WechatOpenLocationTarget): Promise<WechatMiniPro
return navigateToHostLocationPage(bridge, validation.value)
}
const returnOnce = async (): Promise<WechatMiniProgramReturnResult> => {
if (!isEmbeddedInWechatMiniProgram()) return { status: 'not-embedded' }
const bridge = await waitForBridge()
if (!bridge) return { status: 'failed', reason: 'bridge-unavailable' }
if (!await isMiniProgramWebView(bridge)) return { status: 'failed', reason: 'not-in-mini-program' }
return navigateBackToHostPage(bridge)
}
export const openWechatMiniProgramLocation = (target: WechatOpenLocationTarget) => {
if (pendingNavigation) return pendingNavigation
pendingNavigation = openOnce(target).finally(() => { pendingNavigation = null })
return pendingNavigation
}
export const returnToWechatMiniProgram = () => {
if (pendingReturn) return pendingReturn
pendingReturn = returnOnce().finally(() => { pendingReturn = null })
return pendingReturn
}