feat: 添加飞书 JSBridge SDK 支持

问题:
- 移动端飞书 WebView 中 tt 对象没有被注入
- 导致免登功能无法使用

修复:
1. index.html - 引入飞书 H5 JSBridge SDK
2. approval/detail.tsx - 添加对多种飞书 API 的支持
3. debug-feishu.tsx - 更新调试页面,检测所有可能的 API 对象

支持的飞书 API:
- window.tt (标准 H5 应用)
- window.h5sdk (JSBridge)
- window.bridge (JSBridge)
- window.ttjsBridge (旧版)

相关文件:
- frontend/index.html
- frontend/src/pages/approval/detail.tsx
- frontend/src/pages/debug-feishu.tsx

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-02-26 19:21:01 +08:00
parent f31abf2c68
commit 7e57e8720b
3 changed files with 160 additions and 59 deletions
+62 -28
View File
@@ -126,41 +126,75 @@ export default function ApprovalDetail() {
console.log('🔍 tryFeishuLogin 开始')
console.log('📱 isInFeishu:', isInFeishu)
console.log('🔧 window.tt:', window.tt)
console.log('🔧 window.h5sdk:', (window as any).h5sdk)
console.log('🔧 window.bridge:', (window as any).bridge)
if (!isInFeishu || !window.tt) {
console.log('❌ 不在飞书内或 tt 对象不可用,跳过免登')
if (!isInFeishu) {
console.log('❌ 不在飞书内,跳过免登')
resolve(false)
return
}
console.log('🚀 开始调用 tt.requestAuthCode')
const appId = 'cli_a8033d607cba500d'
window.tt.requestAuthCode({
appId: appId,
success: async (res: any) => {
console.log('✅ tt.requestAuthCode 成功:', res)
console.log('🔑 authCode:', res.code?.substring(0, 30) + '...')
try {
console.log('📡 调用后端登录API...')
const result = await authApi.feishuLogin(res.code)
console.log('✅ 后端登录成功:', result.user?.name)
login(result.user, result.token)
Toast.show('登录成功')
resolve(true)
} catch (error) {
console.error('❌ 飞书登录API失败:', error)
Toast.show('登录失败: ' + (error.message || '未知错误'))
const requestAuthCode = (apiObj: any, source: string) => {
console.log(`🚀 使用 ${source} 调用 requestAuthCode`)
apiObj.requestAuthCode({
appId: appId,
success: async (res: any) => {
console.log(`✅ ${source}.requestAuthCode 成功:`, res)
console.log('🔑 authCode:', res.code?.substring(0, 30) + '...')
try {
console.log('📡 调用后端登录API...')
const result = await authApi.feishuLogin(res.code)
console.log('✅ 后端登录成功:', result.user?.name)
login(result.user, result.token)
Toast.show('登录成功')
resolve(true)
} catch (error) {
console.error('❌ 飞书登录API失败:', error)
Toast.show('登录失败: ' + (error.message || '未知错误'))
resolve(false)
}
},
fail: (error: any) => {
console.error(`❌ ${source}.requestAuthCode 失败:`, error)
console.error('❌ 错误详情:', JSON.stringify(error))
Toast.show('免登失败: ' + (error.errorMessage || error.errMsg || '未知错误'))
resolve(false)
}
},
fail: (error: any) => {
console.error('❌ tt.requestAuthCode 失败:', error)
console.error('❌ 错误详情:', JSON.stringify(error))
Toast.show('免登失败: ' + (error.errorMessage || error.errMsg || '未知错误'))
resolve(false)
},
})
},
})
}
// 优先使用 tt 对象
if (window.tt && typeof window.tt.requestAuthCode === 'function') {
requestAuthCode(window.tt, 'tt')
return
}
// 尝试使用 h5sdk
const h5sdk = (window as any).h5sdk
if (h5sdk && typeof h5sdk.requestAuthCode === 'function') {
requestAuthCode(h5sdk, 'h5sdk')
return
}
// 尝试使用 bridge
const bridge = (window as any).bridge
if (bridge && typeof bridge.requestAuthCode === 'function') {
requestAuthCode(bridge, 'bridge')
return
}
// 尝试使用 ttjsBridge
if (window.ttjsBridge && typeof window.ttjsBridge.requestAuthCode === 'function') {
requestAuthCode(window.ttjsBridge, 'ttjsBridge')
return
}
// 所有方法都不可用
console.log('❌ 所有飞书 API 都不可用')
Toast.show('飞书API不可用,请使用其他方式登录')
resolve(false)
})
}