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:
@@ -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(() => {
|
||||
|
||||
Reference in New Issue
Block a user