From f31abf2c685d7ac96ae0f4f6046b42b85e062559 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 26 Feb 2026 19:16:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=A3=9E=E4=B9=A6?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E8=B0=83=E8=AF=95=E9=A1=B5=E9=9D=A2=E5=92=8C?= =?UTF-8?q?=E8=AF=A6=E7=BB=86=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改内容: 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 --- frontend/src/pages/approval/detail.tsx | 53 ++++++++-- frontend/src/pages/debug-feishu.tsx | 131 +++++++++++++++++++++++++ frontend/src/router/index.tsx | 2 + frontend/src/services/business-trip.ts | 2 +- 4 files changed, 180 insertions(+), 8 deletions(-) create mode 100644 frontend/src/pages/debug-feishu.tsx diff --git a/frontend/src/pages/approval/detail.tsx b/frontend/src/pages/approval/detail.tsx index d593a19..04c6c7e 100644 --- a/frontend/src/pages/approval/detail.tsx +++ b/frontend/src/pages/approval/detail.tsx @@ -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]) diff --git a/frontend/src/pages/debug-feishu.tsx b/frontend/src/pages/debug-feishu.tsx new file mode 100644 index 0000000..eeab2a3 --- /dev/null +++ b/frontend/src/pages/debug-feishu.tsx @@ -0,0 +1,131 @@ +import { useEffect, useState } from 'react' +import { Card, List, NoticeBar } from 'antd-mobile' +import { useNavigate } from 'react-router-dom' + +declare global { + interface Window { + tt?: any + ttjsBridge?: any + h5sdk?: any + bridge?: any + } +} + +interface EnvInfo { + ua: string + isInFeishu: boolean + hasTT: boolean + hasTTJSBridge: boolean + hasH5SDK: boolean + hasBridge: boolean + ttMethods: string[] +} + +export default function DebugFeishuPage() { + const navigate = useNavigate() + const [envInfo, setEnvInfo] = useState(null) + + useEffect(() => { + const ua = navigator.userAgent + const isInFeishu = ua.includes('Lark') || ua.includes('feishu') || ua.includes('lark') + + const ttMethods = window.tt ? Object.keys(window.tt) : [] + + setEnvInfo({ + ua, + isInFeishu, + hasTT: !!window.tt, + hasTTJSBridge: !!window.ttjsBridge, + hasH5SDK: !!(window as any).h5sdk, + hasBridge: !!(window as any).bridge, + ttMethods, + }) + + console.log('=== 飞书环境调试 ===') + console.log('User Agent:', ua) + console.log('在飞书中:', isInFeishu) + console.log('window.tt:', window.tt) + console.log('tt 对象方法:', ttMethods) + }, []) + + const testFeishuLogin = async () => { + if (!window.tt) { + alert('tt 对象不存在,无法测试') + return + } + + const appId = 'cli_a8033d607cba500d' + + window.tt.requestAuthCode({ + appId: appId, + success: (res: any) => { + alert('✅ 获取授权码成功: ' + res.code?.substring(0, 30)) + console.log('授权码:', res) + }, + fail: (error: any) => { + alert('❌ 获取授权码失败: ' + JSON.stringify(error)) + console.error('错误:', error) + }, + }) + } + + return ( +
+

飞书环境调试页面

+ + {envInfo && ( + + + 在飞书客户端内 + + + window.tt 对象 + + + window.ttjsBridge 对象 + + + User Agent +
+ {envInfo.ua} +
+
+ + tt 对象方法 ({envInfo.ttMethods.length} 个) +
+ {envInfo.ttMethods.length > 0 ? envInfo.ttMethods.join(', ') : '(无)'} +
+
+
+ )} + + + + 测试飞书免登 + + navigate(-1)} + clickable + arrow + > + 返回 + + + + + + +

1. 在飞书客户端中发送此链接给自己

+

2. 点击链接打开此调试页面

+

3. 查看环境信息

+

4. 点击"测试飞书免登"按钮

+
+
+ ) +} diff --git a/frontend/src/router/index.tsx b/frontend/src/router/index.tsx index b14efe1..350117a 100644 --- a/frontend/src/router/index.tsx +++ b/frontend/src/router/index.tsx @@ -13,6 +13,7 @@ import ApprovalList from '@/pages/approval/list' import ApprovalDetail from '@/pages/approval/detail' import Login from '@/pages/login' import SimpleLogin from '@/pages/login-simple' +import DebugFeishu from '@/pages/debug-feishu' const router = createBrowserRouter([ { @@ -35,6 +36,7 @@ const router = createBrowserRouter([ }, { path: '/login', element: }, { path: '/login-simple', element: }, + { path: '/debug-feishu', element: }, { path: '*', element: }, ]) diff --git a/frontend/src/services/business-trip.ts b/frontend/src/services/business-trip.ts index d3ab870..6140ba3 100644 --- a/frontend/src/services/business-trip.ts +++ b/frontend/src/services/business-trip.ts @@ -1,4 +1,4 @@ -import { api } from './api' +import api from './api' // 出差申请接口类型定义 export interface BusinessTripItinerary {