备货单 添加预览 跟进列表分页 审批记录显示问题处理
This commit is contained in:
+272
-280
@@ -16,288 +16,280 @@ export interface MenuBadgeData {
|
||||
}
|
||||
|
||||
// 菜单徽标Store
|
||||
export const useMenuBadgeStore = defineStore(
|
||||
'menuBadgeStore',
|
||||
() => {
|
||||
// 徽标数据映射 - 使用普通对象而不是Map,避免持久化问题
|
||||
const badgeData = ref<Record<string, MenuBadgeData>>({})
|
||||
export const useMenuBadgeStore = defineStore('menuBadgeStore', () => {
|
||||
// 徽标数据映射 - 使用普通对象而不是Map,避免持久化问题
|
||||
const badgeData = ref<Record<string, MenuBadgeData>>({})
|
||||
|
||||
// 页面是否已加载完成
|
||||
const isPageReady = ref(false)
|
||||
// 页面是否已加载完成
|
||||
const isPageReady = ref(false)
|
||||
|
||||
// 待处理的徽标更新队列(页面未加载完成时使用)
|
||||
const pendingUpdates = ref<Array<{ path: string; count: number; type: 'dot' | 'text' }>>([])
|
||||
// 待处理的徽标更新队列(页面未加载完成时使用)
|
||||
const pendingUpdates = ref<Array<{ path: string; count: number; type: 'dot' | 'text' }>>([])
|
||||
|
||||
// 获取当前用户ID
|
||||
const getCurrentUserId = (): string => {
|
||||
try {
|
||||
const userStore = useUserStore()
|
||||
return userStore.info?.userId?.toString() || 'anonymous'
|
||||
} catch {
|
||||
return 'anonymous'
|
||||
}
|
||||
}
|
||||
|
||||
// 获取用户特定的存储key
|
||||
const getUserStorageKey = (): string => {
|
||||
const userId = getCurrentUserId()
|
||||
return `menu-badge-${userId}`
|
||||
}
|
||||
|
||||
// 从localStorage加载用户特定的徽标数据
|
||||
const loadUserBadgeData = () => {
|
||||
try {
|
||||
const storageKey = getUserStorageKey()
|
||||
const stored = localStorage.getItem(storageKey)
|
||||
if (stored) {
|
||||
const parsed = JSON.parse(stored)
|
||||
badgeData.value = parsed.badgeData || {}
|
||||
isPageReady.value = parsed.isPageReady || false
|
||||
pendingUpdates.value = parsed.pendingUpdates || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('加载用户徽标数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 保存用户特定的徽标数据到localStorage
|
||||
const saveUserBadgeData = () => {
|
||||
try {
|
||||
const storageKey = getUserStorageKey()
|
||||
const data = {
|
||||
badgeData: badgeData.value,
|
||||
isPageReady: isPageReady.value,
|
||||
pendingUpdates: pendingUpdates.value
|
||||
}
|
||||
localStorage.setItem(storageKey, JSON.stringify(data))
|
||||
} catch (error) {
|
||||
console.warn('保存用户徽标数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 清理其他用户的徽标数据
|
||||
const cleanupOtherUserData = () => {
|
||||
try {
|
||||
const currentUserId = getCurrentUserId()
|
||||
const keys = Object.keys(localStorage)
|
||||
keys.forEach((key) => {
|
||||
if (key.startsWith('menu-badge-') && !key.endsWith(`-${currentUserId}`)) {
|
||||
localStorage.removeItem(key)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.warn('清理其他用户数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算属性:获取所有徽标数据
|
||||
const allBadgeData = computed(() => {
|
||||
return { ...badgeData.value }
|
||||
})
|
||||
|
||||
// 获取指定菜单的徽标数据
|
||||
const getBadgeData = (path: string): MenuBadgeData | null => {
|
||||
return badgeData.value[path] || null
|
||||
}
|
||||
|
||||
// 获取指定菜单的徽标数量
|
||||
const getBadgeCount = (path: string): number => {
|
||||
const data = badgeData.value[path]
|
||||
return data?.count || 0
|
||||
}
|
||||
|
||||
// 检查菜单是否应该显示徽标
|
||||
const shouldShowBadge = (path: string): boolean => {
|
||||
const data = badgeData.value[path]
|
||||
return Boolean(data && data.count > 0)
|
||||
}
|
||||
|
||||
// 检查菜单是否应该显示文本徽标
|
||||
const shouldShowTextBadge = (path: string): string | null => {
|
||||
const data = badgeData.value[path]
|
||||
if (data && data.count > 0 && data.type === 'text') {
|
||||
return data.count > 99 ? '99+' : data.count.toString()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// 设置页面加载状态
|
||||
const setPageReady = (ready: boolean) => {
|
||||
isPageReady.value = ready
|
||||
|
||||
// 页面加载完成时,加载用户特定的徽标数据
|
||||
if (ready) {
|
||||
loadUserBadgeData()
|
||||
// 处理待处理的更新
|
||||
if (pendingUpdates.value.length > 0) {
|
||||
// console.log('页面加载完成,处理待处理的徽标更新:', pendingUpdates.value.length)
|
||||
pendingUpdates.value.forEach((update) => {
|
||||
updateBadgeData(update.path, update.count, update.type)
|
||||
})
|
||||
pendingUpdates.value = []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新徽标数据
|
||||
const updateBadgeData = (path: string, count: number, type: 'dot' | 'text' = 'text') => {
|
||||
// 如果页面未加载完成,将更新加入队列
|
||||
if (!isPageReady.value) {
|
||||
// console.log('页面未加载完成,将徽标更新加入队列:', { path, count, type })
|
||||
// 检查是否已存在相同路径的待处理更新,避免重复
|
||||
const existingIndex = pendingUpdates.value.findIndex((item) => item.path === path)
|
||||
if (existingIndex >= 0) {
|
||||
pendingUpdates.value[existingIndex] = { path, count, type }
|
||||
} else {
|
||||
pendingUpdates.value.push({ path, count, type })
|
||||
}
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
return
|
||||
}
|
||||
|
||||
// console.log('更新菜单徽标:', { path, count, type })
|
||||
|
||||
if (count <= 0) {
|
||||
// 如果数量为0或负数,移除徽标
|
||||
delete badgeData.value[path]
|
||||
} else {
|
||||
// 更新或创建徽标数据
|
||||
badgeData.value[path] = {
|
||||
path,
|
||||
count,
|
||||
type,
|
||||
lastUpdated: Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
}
|
||||
|
||||
// 批量更新徽标数据
|
||||
const batchUpdateBadgeData = (
|
||||
updates: Array<{ path: string; count: number; type?: 'dot' | 'text' }>
|
||||
) => {
|
||||
if (!isPageReady.value) {
|
||||
// console.log('页面未加载完成,将批量徽标更新加入队列:', updates.length)
|
||||
updates.forEach((update) => {
|
||||
const existingIndex = pendingUpdates.value.findIndex((item) => item.path === update.path)
|
||||
if (existingIndex >= 0) {
|
||||
pendingUpdates.value[existingIndex] = {
|
||||
path: update.path,
|
||||
count: update.count,
|
||||
type: update.type || 'text'
|
||||
}
|
||||
} else {
|
||||
pendingUpdates.value.push({
|
||||
path: update.path,
|
||||
count: update.count,
|
||||
type: update.type || 'text'
|
||||
})
|
||||
}
|
||||
})
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
return
|
||||
}
|
||||
|
||||
// console.log('批量更新菜单徽标:', updates.length)
|
||||
updates.forEach((update) => {
|
||||
updateBadgeData(update.path, update.count, update.type || 'text')
|
||||
})
|
||||
// 批量更新后保存
|
||||
saveUserBadgeData()
|
||||
}
|
||||
|
||||
// 清除指定菜单的徽标
|
||||
const clearBadge = (path: string) => {
|
||||
updateBadgeData(path, 0)
|
||||
}
|
||||
|
||||
// 清除所有徽标
|
||||
const clearAllBadges = () => {
|
||||
badgeData.value = {}
|
||||
pendingUpdates.value = []
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
}
|
||||
|
||||
// 从菜单列表同步徽标状态
|
||||
const syncBadgeWithMenuList = (menuList: AppRouteRecord[]) => {
|
||||
if (!isPageReady.value) {
|
||||
// console.log('页面未加载完成,跳过菜单徽标同步')
|
||||
return
|
||||
}
|
||||
|
||||
const updateMenuBadge = (menus: AppRouteRecord[]) => {
|
||||
menus.forEach((menu) => {
|
||||
const badgeData = getBadgeData(menu.path)
|
||||
if (badgeData) {
|
||||
// 更新菜单的徽标状态
|
||||
menu.meta.showBadge = badgeData.type === 'dot' && badgeData.count > 0
|
||||
menu.meta.showTextBadge =
|
||||
badgeData.type === 'text' && badgeData.count > 0
|
||||
? badgeData.count > 99
|
||||
? '99+'
|
||||
: badgeData.count.toString()
|
||||
: undefined
|
||||
} else {
|
||||
// 清除菜单的徽标状态
|
||||
menu.meta.showBadge = false
|
||||
menu.meta.showTextBadge = undefined
|
||||
}
|
||||
|
||||
// 递归处理子菜单
|
||||
if (menu.children) {
|
||||
updateMenuBadge(menu.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateMenuBadge(menuList)
|
||||
}
|
||||
|
||||
// 获取待处理更新的数量
|
||||
const getPendingUpdatesCount = () => pendingUpdates.value.length
|
||||
|
||||
// 获取待处理的更新列表
|
||||
const getPendingUpdates = () => [...pendingUpdates.value]
|
||||
|
||||
return {
|
||||
// 状态
|
||||
badgeData,
|
||||
isPageReady,
|
||||
pendingUpdates,
|
||||
|
||||
// 计算属性
|
||||
allBadgeData,
|
||||
|
||||
// 方法
|
||||
getBadgeData,
|
||||
getBadgeCount,
|
||||
shouldShowBadge,
|
||||
shouldShowTextBadge,
|
||||
setPageReady,
|
||||
updateBadgeData,
|
||||
batchUpdateBadgeData,
|
||||
clearBadge,
|
||||
clearAllBadges,
|
||||
syncBadgeWithMenuList,
|
||||
getPendingUpdatesCount,
|
||||
getPendingUpdates,
|
||||
|
||||
// 用户隔离相关方法
|
||||
loadUserBadgeData,
|
||||
saveUserBadgeData,
|
||||
cleanupOtherUserData,
|
||||
getCurrentUserId
|
||||
}
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
key: 'menu-badge',
|
||||
storage: localStorage
|
||||
// 获取当前用户ID
|
||||
const getCurrentUserId = (): string => {
|
||||
try {
|
||||
const userStore = useUserStore()
|
||||
return userStore.info?.userId?.toString() || 'anonymous'
|
||||
} catch {
|
||||
return 'anonymous'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 获取用户特定的存储key
|
||||
const getUserStorageKey = (): string => {
|
||||
const userId = getCurrentUserId()
|
||||
return `menu-badge-${userId}`
|
||||
}
|
||||
|
||||
// 从localStorage加载用户特定的徽标数据
|
||||
const loadUserBadgeData = () => {
|
||||
try {
|
||||
const storageKey = getUserStorageKey()
|
||||
const stored = localStorage.getItem(storageKey)
|
||||
if (stored) {
|
||||
const parsed = JSON.parse(stored)
|
||||
badgeData.value = parsed.badgeData || {}
|
||||
// 注意:不恢复 isPageReady,因为页面状态应该在运行时由代码控制
|
||||
// isPageReady.value 应该在 setPageReady() 中设置,而不是从存储中恢复
|
||||
pendingUpdates.value = parsed.pendingUpdates || []
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('加载用户徽标数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 保存用户特定的徽标数据到localStorage
|
||||
const saveUserBadgeData = () => {
|
||||
try {
|
||||
const storageKey = getUserStorageKey()
|
||||
const data = {
|
||||
badgeData: badgeData.value,
|
||||
// 注意:不保存 isPageReady,因为页面状态应该在运行时由代码控制
|
||||
// 页面每次加载时都应该重新设置为 true
|
||||
pendingUpdates: pendingUpdates.value
|
||||
}
|
||||
localStorage.setItem(storageKey, JSON.stringify(data))
|
||||
} catch (error) {
|
||||
console.warn('保存用户徽标数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 清理其他用户的徽标数据
|
||||
const cleanupOtherUserData = () => {
|
||||
try {
|
||||
const currentUserId = getCurrentUserId()
|
||||
const keys = Object.keys(localStorage)
|
||||
keys.forEach((key) => {
|
||||
if (key.startsWith('menu-badge-') && !key.endsWith(`-${currentUserId}`)) {
|
||||
localStorage.removeItem(key)
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.warn('清理其他用户数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 计算属性:获取所有徽标数据
|
||||
const allBadgeData = computed(() => {
|
||||
return { ...badgeData.value }
|
||||
})
|
||||
|
||||
// 获取指定菜单的徽标数据
|
||||
const getBadgeData = (path: string): MenuBadgeData | null => {
|
||||
return badgeData.value[path] || null
|
||||
}
|
||||
|
||||
// 获取指定菜单的徽标数量
|
||||
const getBadgeCount = (path: string): number => {
|
||||
const data = badgeData.value[path]
|
||||
return data?.count || 0
|
||||
}
|
||||
|
||||
// 检查菜单是否应该显示徽标
|
||||
const shouldShowBadge = (path: string): boolean => {
|
||||
const data = badgeData.value[path]
|
||||
return Boolean(data && data.count > 0)
|
||||
}
|
||||
|
||||
// 检查菜单是否应该显示文本徽标
|
||||
const shouldShowTextBadge = (path: string): string | null => {
|
||||
const data = badgeData.value[path]
|
||||
if (data && data.count > 0 && data.type === 'text') {
|
||||
return data.count > 99 ? '99+' : data.count.toString()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// 设置页面加载状态
|
||||
const setPageReady = (ready: boolean) => {
|
||||
isPageReady.value = ready
|
||||
|
||||
// 页面加载完成时,加载用户特定的徽标数据
|
||||
if (ready) {
|
||||
loadUserBadgeData()
|
||||
// 确保 isPageReady 保持为 true(防止被其他逻辑覆盖)
|
||||
isPageReady.value = true
|
||||
// 处理待处理的更新
|
||||
if (pendingUpdates.value.length > 0) {
|
||||
pendingUpdates.value.forEach((update) => {
|
||||
updateBadgeData(update.path, update.count, update.type)
|
||||
})
|
||||
pendingUpdates.value = []
|
||||
// 再次确认页面状态
|
||||
isPageReady.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新徽标数据
|
||||
const updateBadgeData = (path: string, count: number, type: 'dot' | 'text' = 'text') => {
|
||||
// 如果页面未加载完成,将更新加入队列
|
||||
if (!isPageReady.value) {
|
||||
// console.log('页面未加载完成,将徽标更新加入队列:', { path, count, type })
|
||||
// 检查是否已存在相同路径的待处理更新,避免重复
|
||||
const existingIndex = pendingUpdates.value.findIndex((item) => item.path === path)
|
||||
if (existingIndex >= 0) {
|
||||
pendingUpdates.value[existingIndex] = { path, count, type }
|
||||
} else {
|
||||
pendingUpdates.value.push({ path, count, type })
|
||||
}
|
||||
console.log('检查菜单是否应该显示徽标:', path, badgeData.value)
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
return
|
||||
}
|
||||
|
||||
if (count <= 0) {
|
||||
// 如果数量为0或负数,移除徽标
|
||||
delete badgeData.value[path]
|
||||
} else {
|
||||
// 更新或创建徽标数据
|
||||
badgeData.value[path] = {
|
||||
path,
|
||||
count,
|
||||
type,
|
||||
lastUpdated: Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
}
|
||||
|
||||
// 批量更新徽标数据
|
||||
const batchUpdateBadgeData = (
|
||||
updates: Array<{ path: string; count: number; type?: 'dot' | 'text' }>
|
||||
) => {
|
||||
if (!isPageReady.value) {
|
||||
updates.forEach((update) => {
|
||||
const existingIndex = pendingUpdates.value.findIndex((item) => item.path === update.path)
|
||||
if (existingIndex >= 0) {
|
||||
pendingUpdates.value[existingIndex] = {
|
||||
path: update.path,
|
||||
count: update.count,
|
||||
type: update.type || 'text'
|
||||
}
|
||||
} else {
|
||||
pendingUpdates.value.push({
|
||||
path: update.path,
|
||||
count: update.count,
|
||||
type: update.type || 'text'
|
||||
})
|
||||
}
|
||||
})
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
return
|
||||
}
|
||||
updates.forEach((update) => {
|
||||
updateBadgeData(update.path, update.count, update.type || 'text')
|
||||
})
|
||||
// 批量更新后保存
|
||||
saveUserBadgeData()
|
||||
}
|
||||
|
||||
// 清除指定菜单的徽标
|
||||
const clearBadge = (path: string) => {
|
||||
updateBadgeData(path, 0)
|
||||
}
|
||||
|
||||
// 清除所有徽标
|
||||
const clearAllBadges = () => {
|
||||
badgeData.value = {}
|
||||
pendingUpdates.value = []
|
||||
// 保存到用户特定存储
|
||||
saveUserBadgeData()
|
||||
}
|
||||
|
||||
// 从菜单列表同步徽标状态
|
||||
const syncBadgeWithMenuList = (menuList: AppRouteRecord[]) => {
|
||||
if (!isPageReady.value) {
|
||||
// console.log('页面未加载完成,跳过菜单徽标同步')
|
||||
return
|
||||
}
|
||||
|
||||
const updateMenuBadge = (menus: AppRouteRecord[]) => {
|
||||
menus.forEach((menu) => {
|
||||
const badgeData = getBadgeData(menu.path)
|
||||
if (badgeData) {
|
||||
// 更新菜单的徽标状态
|
||||
menu.meta.showBadge = badgeData.type === 'dot' && badgeData.count > 0
|
||||
menu.meta.showTextBadge =
|
||||
badgeData.type === 'text' && badgeData.count > 0
|
||||
? badgeData.count > 99
|
||||
? '99+'
|
||||
: badgeData.count.toString()
|
||||
: undefined
|
||||
} else {
|
||||
// 清除菜单的徽标状态
|
||||
menu.meta.showBadge = false
|
||||
menu.meta.showTextBadge = undefined
|
||||
}
|
||||
|
||||
// 递归处理子菜单
|
||||
if (menu.children) {
|
||||
updateMenuBadge(menu.children)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateMenuBadge(menuList)
|
||||
}
|
||||
|
||||
// 获取待处理更新的数量
|
||||
const getPendingUpdatesCount = () => pendingUpdates.value.length
|
||||
|
||||
// 获取待处理的更新列表
|
||||
const getPendingUpdates = () => [...pendingUpdates.value]
|
||||
|
||||
return {
|
||||
// 状态
|
||||
badgeData,
|
||||
isPageReady,
|
||||
pendingUpdates,
|
||||
|
||||
// 计算属性
|
||||
allBadgeData,
|
||||
|
||||
// 方法
|
||||
getBadgeData,
|
||||
getBadgeCount,
|
||||
shouldShowBadge,
|
||||
shouldShowTextBadge,
|
||||
setPageReady,
|
||||
updateBadgeData,
|
||||
batchUpdateBadgeData,
|
||||
clearBadge,
|
||||
clearAllBadges,
|
||||
syncBadgeWithMenuList,
|
||||
getPendingUpdatesCount,
|
||||
getPendingUpdates,
|
||||
|
||||
// 用户隔离相关方法
|
||||
loadUserBadgeData,
|
||||
saveUserBadgeData,
|
||||
cleanupOtherUserData,
|
||||
getCurrentUserId
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user