fix: 合并 useEffect 逻辑,修复默认审批人不显示的问题

问题原因:两个 useEffect 执行顺序冲突
- 第一个 useEffect 加载默认数据
- 第二个 useEffect 又清除了人员数据

解决方案:合并为一个统一的 useEffect,按优先级处理:
1. 从选择页面返回 -> 恢复 sessionStorage 数据
2. 有草稿数据 -> 恢复草稿及关联人员数据
3. 首次进入 -> 清除旧数据,加载默认配置

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-02-25 19:03:53 +08:00
parent be2e56995e
commit 0ee7cb6f49
+77 -123
View File
@@ -86,40 +86,89 @@ export default function BusinessTripApply() {
// 使用 ref 来跟踪是否已经恢复过草稿
const hasRestoredRef = useRef(false)
// 加载默认审批人和抄送人(仅在首次加载且没有草稿数据时)
const defaultLoadedRef = useRef(false)
// 统一处理:草稿恢复、默认审批人加载、选择页面返回
const initRef = useRef(false)
useEffect(() => {
// 防止重复执行
if (initRef.current) {
// 只有从选择页面返回时才重新执行
if (!location.state?.fromSelection) {
return
}
}
const fromSelection = location.state?.fromSelection
console.log('📍 Page init:', { fromSelection, path: location.pathname })
// 1. 从选择页面返回:恢复所有人员数据
if (fromSelection) {
console.log('🔄 Returning from selection page')
const approversData = sessionStorage.getItem('selectedApprovers')
if (approversData) {
const approvers = JSON.parse(approversData) as ApproverItem[]
setApprovers(approvers)
console.log('✅ Restored approvers:', approvers)
} else {
setApprovers([])
}
const ccData = sessionStorage.getItem('selectedCc')
if (ccData) {
const cc = JSON.parse(ccData) as ApproverItem[]
setCcUsers(cc)
console.log('✅ Restored CC:', cc)
} else {
setCcUsers([])
}
initRef.current = true
return
}
// 2. 恢复草稿数据(理由、行程)
const draftData = sessionStorage.getItem('businessTripDraft')
if (draftData) {
console.log('📦 Restoring draft data')
try {
const draft = JSON.parse(draftData)
if (draft.reason) setReason(draft.reason)
if (draft.itineraries && draft.itineraries.length > 0) {
const restoredItineraries = draft.itineraries.map((item: any) => ({
...item,
startTime: item.startTime ? new Date(item.startTime) : null,
endTime: item.endTime ? new Date(item.endTime) : null,
}))
setItineraries(restoredItineraries)
}
} catch (error) {
console.error('❌ Failed to restore draft:', error)
}
}
// 3. 加载默认审批人和抄送人(仅在首次且无草稿时)
const loadDefaultApprovers = async () => {
// 防止重复加载
if (defaultLoadedRef.current) return
if (initRef.current) return
initRef.current = true
// 如果已经有存储的草稿数据,不加载默认值
if (sessionStorage.getItem('businessTripDraft')) {
defaultLoadedRef.current = true
return
}
// 如果已经从选择页面返回,不加载默认值
if (location.state?.fromSelection) {
defaultLoadedRef.current = true
return
}
// 如果已经有存储的人员数据,恢复但不标记为已加载(允许后续更新)
const storedApprovers = sessionStorage.getItem('selectedApprovers')
const storedCc = sessionStorage.getItem('selectedCc')
if (storedApprovers || storedCc) {
if (storedApprovers) {
setApprovers(JSON.parse(storedApprovers))
}
if (storedCc) {
setCcUsers(JSON.parse(storedCc))
}
defaultLoadedRef.current = true
// 如果有草稿数据,不加载默认值
if (draftData) {
console.log('⏭️ Skipping default load (has draft)')
// 恢复草稿关联的人员数据
const approversData = sessionStorage.getItem('selectedApprovers')
const ccData = sessionStorage.getItem('selectedCc')
if (approversData) setApprovers(JSON.parse(approversData))
if (ccData) setCcUsers(JSON.parse(ccData))
return
}
// 从后端获取默认配置
// 清除旧数据,加载默认配置
console.log('🔄 Loading default approvers from backend...')
sessionStorage.removeItem('selectedApprovers')
sessionStorage.removeItem('selectedCc')
try {
const defaultData = await businessTripApi.getDefaultApprovers()
console.log('✅ Default approvers:', defaultData)
if (defaultData.approvers && defaultData.approvers.length > 0) {
setApprovers(defaultData.approvers)
sessionStorage.setItem('selectedApprovers', JSON.stringify(defaultData.approvers))
@@ -129,107 +178,12 @@ export default function BusinessTripApply() {
sessionStorage.setItem('selectedCc', JSON.stringify(defaultData.cc_users))
}
} catch (error) {
console.error('Failed to load default approvers:', error)
console.error('❌ Failed to load default approvers:', error)
}
defaultLoadedRef.current = true
}
loadDefaultApprovers()
}, [])
// 处理从选择页面返回的数据和草稿恢复
useEffect(() => {
const fromSelection = location.state?.fromSelection
console.log('📍 Page loaded/updated:', {
fromSelection,
path: location.pathname
})
// 恢复草稿数据(每次组件挂载都需要恢复)
const draftData = sessionStorage.getItem('businessTripDraft')
console.log('📦 Draft data in sessionStorage:', draftData)
if (draftData) {
try {
const draft = JSON.parse(draftData)
console.log('📄 Parsed draft:', draft)
// 恢复理由
if (draft.reason) {
console.log('✏️ Restoring reason:', draft.reason)
setReason(draft.reason)
}
// 恢复行程数据
if (draft.itineraries && draft.itineraries.length > 0) {
const restoredItineraries = draft.itineraries.map((item: any) => ({
...item,
startTime: item.startTime ? new Date(item.startTime) : null,
endTime: item.endTime ? new Date(item.endTime) : null,
}))
console.log('🛤️ Restoring itineraries:', restoredItineraries)
setItineraries(restoredItineraries)
}
// 有草稿数据,也尝试恢复人员数据
if (!fromSelection) {
const approversData = sessionStorage.getItem('selectedApprovers')
if (approversData) {
const approvers = JSON.parse(approversData) as ApproverItem[]
setApprovers(approvers)
console.log('✅ Restored approvers (with draft):', approvers)
}
const ccData = sessionStorage.getItem('selectedCc')
if (ccData) {
const cc = JSON.parse(ccData) as ApproverItem[]
setCcUsers(cc)
console.log('✅ Restored CC (with draft):', cc)
}
}
} catch (error) {
console.error('❌ Failed to restore draft:', error)
}
} else {
console.log('⚠️ No draft data found in sessionStorage')
// 没有草稿数据,清除旧的人员选择数据(开始新申请)
if (!fromSelection) {
console.log('🧹 Clearing old selection data (new application)')
sessionStorage.removeItem('selectedApprovers')
sessionStorage.removeItem('selectedCc')
setApprovers([])
setCcUsers([])
}
}
// 从选择页面返回,恢复所有人员数据
if (fromSelection) {
console.log('🔄 Returning from selection page')
const type = location.state?.type
console.log('📋 Selection type:', type)
// 恢复所有人员数据(审批人 + 抄送人)
const approversData = sessionStorage.getItem('selectedApprovers')
if (approversData) {
const approvers = JSON.parse(approversData) as ApproverItem[]
setApprovers(approvers)
console.log('✅ Restored approvers from sessionStorage:', approvers)
} else {
setApprovers([])
}
const ccData = sessionStorage.getItem('selectedCc')
if (ccData) {
const cc = JSON.parse(ccData) as ApproverItem[]
setCcUsers(cc)
console.log('✅ Restored CC from sessionStorage:', cc)
} else {
setCcUsers([])
}
}
}, [location.state, location.pathname])
}, [location.state])
// 计算总时长(累加所有行程的天数)
const totalDuration = useMemo(() => {