fix: 修复审批列表首次加载不显示和发起人审批人问题
- 移除 loadingRef,解决 React 18 StrictMode 下请求阻塞问题 - 提交申请时根据选择的审批人动态创建/更新审批节点 - 修改申请提交后跳转到审批列表而非出差列表 - 更新 PROJECT_ISSUES.md 记录所有问题和解决方案 修复问题: 1. 首次进入审批列表"我发起的"不显示数据 2. 发起人也是审批人时"待我审批"不显示 3. 申请提交后跳转到错误的页面 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -49,31 +49,19 @@ export default function ApprovalList() {
|
||||
const [activeTab, setActiveTab] = useState<'my' | 'pending' | 'approved'>('my')
|
||||
const [list, setList] = useState<ApprovalItem[]>([])
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [hasMore, setHasMore] = useState(false) // 改为 false,避免挂载时立即触发加载更多
|
||||
const [hasMore, setHasMore] = useState(false)
|
||||
const [page, setPage] = useState(1)
|
||||
const currentTabRef = useRef(activeTab) // 用于追踪当前有效的 tab
|
||||
const loadingRef = useRef(false) // 用于同步追踪 loading 状态
|
||||
const requestIdRef = useRef<string | null>(null) // 用于追踪当前请求 ID
|
||||
const mountedRef = useRef(true) // 组件挂载时立即设为 true
|
||||
|
||||
// 更新 ref 当 activeTab 变化时
|
||||
useEffect(() => {
|
||||
currentTabRef.current = activeTab
|
||||
}, [activeTab])
|
||||
const requestIdRef = useRef<string>('')
|
||||
|
||||
// 加载数据 - 接收 tab 参数避免使用旧的 activeTab
|
||||
// 加载数据 - 接收 tab 参数
|
||||
const loadData = async (pageNum: number = 1, isRefresh: boolean = false, tab?: string) => {
|
||||
// 使用 ref 检查 loading,避免 React 18 StrictMode 双重调用
|
||||
if (loadingRef.current) {
|
||||
console.log('⏸️ Request blocked - already loading')
|
||||
return
|
||||
}
|
||||
|
||||
// 使用传入的 tab 参数,如果没有则使用当前 activeTab
|
||||
const currentTab = tab || activeTab
|
||||
const requestId = `${currentTab}-${pageNum}-${Date.now()}`
|
||||
// 生成新的请求 ID
|
||||
const requestId = `${tab || activeTab}-${pageNum}-${Date.now()}-${Math.random()}`
|
||||
requestIdRef.current = requestId
|
||||
|
||||
const currentTab = tab || activeTab
|
||||
|
||||
console.log('🔍 Loading approval list START:', {
|
||||
requestId,
|
||||
currentTab,
|
||||
@@ -81,11 +69,11 @@ export default function ApprovalList() {
|
||||
tab,
|
||||
pageNum,
|
||||
isRefresh,
|
||||
currentTabRef: currentTabRef.current
|
||||
requestIdRefNow: requestIdRef.current
|
||||
})
|
||||
|
||||
loadingRef.current = true
|
||||
setLoading(true)
|
||||
|
||||
try {
|
||||
const result = await approvalApi.getList({
|
||||
type: currentTab,
|
||||
@@ -95,34 +83,30 @@ export default function ApprovalList() {
|
||||
|
||||
console.log('📦 API response received:', {
|
||||
requestId,
|
||||
type: currentTab,
|
||||
count: result?.list?.length,
|
||||
currentTabRefNow: currentTabRef.current
|
||||
currentTab,
|
||||
requestIdRefNow: requestIdRef.current,
|
||||
count: result?.list?.length
|
||||
})
|
||||
|
||||
// 检查是否是最新的请求
|
||||
if (requestIdRef.current !== requestId) {
|
||||
console.log('⏭️ Skipping outdated response:', { requestId, latestRequestId: requestIdRef.current })
|
||||
console.log('⏭️ Skipping outdated response:', {
|
||||
requestId,
|
||||
latestRequestId: requestIdRef.current
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
console.log('📦 API response validated - processing data')
|
||||
|
||||
const newList = result?.list || []
|
||||
|
||||
// 只在当前 tab 与请求的 tab 一致时才更新数据
|
||||
if (currentTabRef.current === currentTab) {
|
||||
console.log('✅ Updating list for tab:', currentTab, 'items:', newList.length)
|
||||
setList(newList)
|
||||
setHasMore(newList.length >= 20)
|
||||
setPage(pageNum)
|
||||
} else {
|
||||
console.log('⏭️ Skipping update - tab changed from', currentTab, 'to', currentTabRef.current)
|
||||
}
|
||||
// 直接更新数据
|
||||
console.log('✅ Updating list for tab:', currentTab, 'items:', newList.length)
|
||||
setList(newList)
|
||||
setHasMore(newList.length >= 20)
|
||||
setPage(pageNum)
|
||||
} catch (error: any) {
|
||||
console.error('Failed to load approvals:', error)
|
||||
console.error('❌ Failed to load approvals:', error)
|
||||
} finally {
|
||||
loadingRef.current = false
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
@@ -130,12 +114,11 @@ export default function ApprovalList() {
|
||||
// 切换标签
|
||||
const handleTabChange = (key: string) => {
|
||||
console.log('🔄 Tab changing from', activeTab, 'to', key)
|
||||
currentTabRef.current = key as 'my' | 'pending' | 'approved' // 立即更新 ref
|
||||
setActiveTab(key as 'my' | 'pending' | 'approved')
|
||||
setList([])
|
||||
setHasMore(true)
|
||||
setHasMore(false)
|
||||
setPage(1)
|
||||
// 直接传入新的 tab 值,避免使用旧的 activeTab
|
||||
// 直接传入新的 tab 值
|
||||
loadData(1, true, key)
|
||||
}
|
||||
|
||||
@@ -151,15 +134,11 @@ export default function ApprovalList() {
|
||||
|
||||
// 初始加载
|
||||
useEffect(() => {
|
||||
mountedRef.current = true
|
||||
// 强制使用页码 1,忽略当前 page 状态
|
||||
console.log('🚀 Initial load effect, forcing page=1')
|
||||
console.log('🚀 Initial load effect')
|
||||
loadData(1, true)
|
||||
|
||||
return () => {
|
||||
console.log('🧹 Cleanup function called')
|
||||
mountedRef.current = false
|
||||
// 不清空 requestIdRef,让异步请求能够正常完成处理
|
||||
}
|
||||
}, [])
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ export default function BusinessTripApply() {
|
||||
sessionStorage.removeItem('businessTripDraft')
|
||||
|
||||
Toast.show('草稿已保存')
|
||||
navigate('/business-trip')
|
||||
navigate('/approval')
|
||||
} catch (error: any) {
|
||||
Toast.show(error.message || '保存失败')
|
||||
}
|
||||
@@ -336,7 +336,7 @@ export default function BusinessTripApply() {
|
||||
sessionStorage.removeItem('businessTripDraft')
|
||||
|
||||
Toast.show(t('businessTrip.submitSuccess'))
|
||||
navigate('/business-trip')
|
||||
navigate('/approval')
|
||||
} catch (error: any) {
|
||||
Toast.show(error.message || '提交失败')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user