fix: 修复快速审批页面路由和错误处理
修复内容: 1. router/index.tsx - 将 QuickAction 路由移到 MobileLayout 外部 2. quick-action.tsx - 修复导入错误,增强错误处理和调试信息 问题分析: - QuickAction 不需要 MobileLayout,应该作为独立页面 - 添加详细的调试日志便于排查问题 - 增强页面关闭逻辑(支持多种方式) 工作流程: 1. 用户点击飞书消息按钮 2. 打开快速审批页面 3. 检查登录状态,未登录则跳转登录页 4. 已登录则自动执行审批操作 5. 显示操作结果 6. 尝试关闭页面或跳转到列表 相关文件: - frontend/src/router/index.tsx - frontend/src/pages/approval/quick-action.tsx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,81 +1,157 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useNavigate, useLocation } from 'react-router-dom'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { SpinLoading, Toast } from 'antd-mobile'
|
||||
import { approvalApi } from '@/services/api'
|
||||
|
||||
export default function QuickAction() {
|
||||
const navigate = useNavigate()
|
||||
const location = useLocation()
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [status, setStatus] = useState('processing')
|
||||
const [message, setMessage] = useState('处理中...')
|
||||
|
||||
useEffect(() => {
|
||||
console.log('🚀 QuickAction 页面加载')
|
||||
|
||||
const processAction = async () => {
|
||||
try {
|
||||
const urlParams = new URLSearchParams(window.location.search)
|
||||
const action = urlParams.get('action') as 'approve' | 'reject' | null
|
||||
const action = urlParams.get('action')
|
||||
const orderId = urlParams.get('order_id')
|
||||
const token = localStorage.getItem('token')
|
||||
|
||||
console.log('🚀 快速审批:', { action, orderId, hasToken: !!token })
|
||||
console.log('🚀 快速审批参数:', { action, orderId, hasToken: !!token })
|
||||
|
||||
if (!action || !orderId) {
|
||||
setStatus('error')
|
||||
setMessage('参数错误')
|
||||
Toast.show('参数错误')
|
||||
setTimeout(() => navigate('/login', { replace: true }), 1500)
|
||||
setTimeout(() => {
|
||||
window.location.href = '/login'
|
||||
}, 2000)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否登录
|
||||
if (!token) {
|
||||
console.log('⚠️ 未登录,跳转到登录页')
|
||||
console.log('⚠️ 未登录')
|
||||
setStatus('unauthorized')
|
||||
setMessage('请先登录')
|
||||
Toast.show('请先登录')
|
||||
setTimeout(() => {
|
||||
window.location.href = '/login?redirect=' + encodeURIComponent(window.location.pathname + window.location.search)
|
||||
}, 1500)
|
||||
const currentUrl = window.location.pathname + window.location.search
|
||||
window.location.href = '/login?redirect=' + encodeURIComponent(currentUrl)
|
||||
}, 2000)
|
||||
return
|
||||
}
|
||||
|
||||
setStatus('processing')
|
||||
setMessage('正在执行审批...')
|
||||
|
||||
// 执行审批操作
|
||||
console.log('📝 执行审批操作:', action, 'order_id:', orderId)
|
||||
|
||||
let result
|
||||
if (action === 'approve') {
|
||||
console.log('✅ 执行通过操作')
|
||||
await approvalApi.approve(Number(orderId), '')
|
||||
Toast.show('已通过')
|
||||
console.log('✅ 调用 approve API')
|
||||
result = await approvalApi.approve(Number(orderId), '')
|
||||
setMessage('已通过')
|
||||
} else if (action === 'reject') {
|
||||
console.log('❌ 执行拒绝操作')
|
||||
await approvalApi.reject(Number(orderId), '已拒绝')
|
||||
Toast.show('已拒绝')
|
||||
console.log('❌ 调用 reject API')
|
||||
result = await approvalApi.reject(Number(orderId), '已拒绝')
|
||||
setMessage('已拒绝')
|
||||
} else {
|
||||
throw new Error('未知操作类型')
|
||||
}
|
||||
|
||||
console.log('✅ 审批操作完成:', result)
|
||||
setStatus('success')
|
||||
|
||||
// 操作成功后关闭页面(在飞书客户端中)
|
||||
// 操作成功后关闭页面
|
||||
setTimeout(() => {
|
||||
console.log('✅ 操作完成,关闭页面')
|
||||
// 在飞书客户端中,关闭当前页面
|
||||
if ((window as any).tt && (window as any).tt.close) {
|
||||
(window as any).tt.close()
|
||||
} else {
|
||||
// 其他情况跳转到审批列表
|
||||
console.log('✅ 操作完成,尝试关闭页面')
|
||||
|
||||
// 尝试关闭页面(在飞书客户端或新窗口中)
|
||||
try {
|
||||
// 尝试飞书关闭方法
|
||||
if ((window as any).tt && typeof (window as any).tt.close === 'function') {
|
||||
console.log('🔒 使用 tt.close() 关闭页面')
|
||||
;(window as any).tt.close()
|
||||
} else if ((window as any).webkit && typeof (window as any).webkit.messageHandlers.postMessage === 'object') {
|
||||
console.log('📱 尝试 iOS WKWebView 关闭')
|
||||
;(window as any).webkit.messageHandlers.postMessage({ action: 'close' })
|
||||
} else if (typeof window.close === 'function') {
|
||||
console.log('🌐 使用 window.close() 关闭')
|
||||
window.close()
|
||||
} else {
|
||||
console.log('📋 无法关闭页面,跳转到审批列表')
|
||||
navigate('/approval', { replace: true })
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('⚠️ 关闭页面失败,跳转到列表')
|
||||
navigate('/approval', { replace: true })
|
||||
}
|
||||
}, 1000)
|
||||
}, 1500)
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('❌ 操作失败:', error)
|
||||
setStatus('error')
|
||||
Toast.show(error.message || '操作失败')
|
||||
setTimeout(() => navigate('/approval', { replace: true }), 2000)
|
||||
setMessage('操作失败: ' + (error.message || '未知错误'))
|
||||
Toast.show('操作失败: ' + (error.message || '未知错误'))
|
||||
setTimeout(() => {
|
||||
navigate('/approval', { replace: true })
|
||||
}, 2000)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
processAction()
|
||||
}, [])
|
||||
// 延迟一点执行,确保页面完全加载
|
||||
setTimeout(processAction, 100)
|
||||
}, [navigate])
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '100vh',
|
||||
background: '#f5f5f5',
|
||||
padding: '20px',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
{loading && (
|
||||
<>
|
||||
<SpinLoading color='primary' />
|
||||
<p style={{ marginTop: '16px', color: '#999' }}>{message}</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
{status === 'success' && (
|
||||
<>
|
||||
<div style={{ fontSize: '64px' }}>✅</div>
|
||||
<p style={{ marginTop: '16px', color: '#52c41a', fontSize: '18px' }}>{message}</p>
|
||||
<p style={{ fontSize: '14px', color: '#999' }}>页面即将关闭...</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
{status === 'error' && (
|
||||
<>
|
||||
<div style={{ fontSize: '64px' }}>❌</div>
|
||||
<p style={{ marginTop: '16px', color: '#ff4d4f', fontSize: '18px' }}>{message}</p>
|
||||
</>
|
||||
)}
|
||||
|
||||
{status === 'unauthorized' && (
|
||||
<>
|
||||
<div style={{ fontSize: '64px }}>🔒</div>
|
||||
<p style={{ marginTop: '16px', color: '#ff8800', fontSize: '18px' }}>需要登录</p>
|
||||
<p style={{ fontSize: '14px', color: '#999' }}>正在跳转到登录页面...</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
|
||||
@@ -33,12 +33,12 @@ const router = createBrowserRouter([
|
||||
{ path: 'business-trip/:id', element: <BusinessTripDetail /> },
|
||||
{ path: 'approval', element: <ApprovalList /> },
|
||||
{ path: 'approval/:id', element: <ApprovalDetail /> },
|
||||
{ path: 'approval/quick-action', element: <QuickAction /> },
|
||||
],
|
||||
},
|
||||
{ path: '/login', element: <Login /> },
|
||||
{ path: '/login-simple', element: <SimpleLogin /> },
|
||||
{ path: '/debug-feishu', element: <DebugFeishu /> },
|
||||
{ path: '/approval/quick-action', element: <QuickAction /> },
|
||||
{ path: '*', element: <Navigate to='/login' replace /> },
|
||||
])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user