feat: 添加飞书环境调试页面和详细日志

修改内容:
1. 新增 debug-feishu.tsx - 飞书环境调试页面
2. approval/detail.tsx - 添加详细的调试日志
3. router/index.tsx - 添加调试页面路由
4. business-trip.ts - 修复 import 错误

调试页面功能:
- 检测是否在飞书客户端内
- 显示 window.tt 等对象状态
- 测试飞书免登功能

使用方法:
1. 在飞书客户端中打开: https://xsm.dev.hnxinyouhe.com/debug-feishu
2. 查看环境信息
3. 点击"测试飞书免登"按钮

相关文件:
- frontend/src/pages/debug-feishu.tsx
- frontend/src/pages/approval/detail.tsx
- frontend/src/router/index.tsx
- frontend/src/services/business-trip.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-02-26 19:16:33 +08:00
parent 3ad8f34914
commit f31abf2c68
4 changed files with 180 additions and 8 deletions
+46 -7
View File
@@ -123,31 +123,41 @@ export default function ApprovalDetail() {
const ua = navigator.userAgent
const isInFeishu = ua.includes('Lark') || ua.includes('feishu') || ua.includes('lark')
console.log('🔍 tryFeishuLogin 开始')
console.log('📱 isInFeishu:', isInFeishu)
console.log('🔧 window.tt:', window.tt)
if (!isInFeishu || !window.tt) {
console.log('❌ 不在飞书内或 tt 对象不可用')
console.log('❌ 不在飞书内或 tt 对象不可用,跳过免登')
resolve(false)
return
}
console.log('🚀 尝试飞书免登')
console.log('🚀 开始调用 tt.requestAuthCode')
const appId = 'cli_a8033d607cba500d'
window.tt.requestAuthCode({
appId: appId,
success: async (res: any) => {
console.log('✅ 飞书免登成功:', res.code?.substring(0, 20))
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 || '未知错误'))
resolve(false)
}
},
fail: (error: any) => {
console.error('❌ 飞书免登失败:', error)
console.error('❌ tt.requestAuthCode 失败:', error)
console.error('❌ 错误详情:', JSON.stringify(error))
Toast.show('免登失败: ' + (error.errorMessage || error.errMsg || '未知错误'))
resolve(false)
},
})
@@ -158,35 +168,53 @@ export default function ApprovalDetail() {
const loadDetail = async () => {
if (!id) return
// 检查登录状态,如果未登录且在飞书内,先尝试飞书免登
console.log('📋 loadDetail 开始, id:', id)
// 检查登录状态
const token = localStorage.getItem('token')
const isLoggedIn = !!user
console.log('🔐 登录状态检查:', { isLoggedIn: !!isLoggedIn, hasToken: !!token, userId: user?.id })
if (!isLoggedIn && !token) {
console.log('⚠️ 用户未登录,检查飞书环境')
const ua = navigator.userAgent
const isInFeishu = ua.includes('Lark') || ua.includes('feishu') || ua.includes('lark')
console.log('📱 飞书环境检测:', { isInFeishu, ua: ua.substring(0, 100) })
console.log('🔧 tt 对象:', window.tt)
if (isInFeishu && window.tt && !tryingFeishuLogin) {
console.log('🚀 开始飞书免登...')
setTryingFeishuLogin(true)
const success = await tryFeishuLogin()
setTryingFeishuLogin(false)
console.log('✅ 免登结果:', success)
if (!success) {
// 免登失败,跳转到登录页面
console.log('❌ 免登失败,跳转登录页')
Toast.show('免登失败,请使用其他方式登录')
window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname + window.location.search)
return
}
console.log('✅ 免登成功,继续加载详情')
} else {
// 不在飞书内或免登不可用,跳转到登录页面
console.log('⚠️ 不在飞书内或 tt 对象不可用')
Toast.show('请先登录')
window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname + window.location.search)
return
}
} else {
console.log('✅ 用户已登录,直接加载详情')
}
console.log('🔄 开始加载审批详情...')
setLoading(true)
try {
const data = await approvalApi.getDetail(Number(id))
console.log('✅ 详情加载成功:', data)
setDetail(data)
} catch (error: any) {
console.error('❌ 详情加载失败:', error)
Toast.show(error.message || '加载失败')
navigate(-1)
} finally {
@@ -195,6 +223,17 @@ export default function ApprovalDetail() {
}
useEffect(() => {
console.log('🔍 ApprovalDetail mount, id:', id)
console.log('🔍 User:', user)
console.log('🔍 Token:', localStorage.getItem('token')?.substring(0, 20) + '...')
// 检查飞书环境
const ua = navigator.userAgent
const isInFeishu = ua.includes('Lark') || ua.includes('feishu') || ua.includes('lark')
console.log('🔍 User Agent:', ua)
console.log('🔍 在飞书中:', isInFeishu)
console.log('🔍 window.tt:', window.tt)
loadDetail()
}, [id])