diff --git a/src/components/core/forms/MultiFileUpload.vue b/src/components/core/forms/MultiFileUpload.vue index 5c15d76..30fbe83 100644 --- a/src/components/core/forms/MultiFileUpload.vue +++ b/src/components/core/forms/MultiFileUpload.vue @@ -31,12 +31,10 @@ {{ file.name }}
- + + 预览 + + 下载
+ diff --git a/src/components/custom/FilePreview.vue b/src/components/custom/FilePreview.vue index 05c8df9..bdf4410 100644 --- a/src/components/custom/FilePreview.vue +++ b/src/components/custom/FilePreview.vue @@ -27,6 +27,7 @@
{{ file.name }} + 预览 下载
@@ -37,13 +38,14 @@ {{ emptyText }} + + + diff --git a/src/composables/useMenuBadge.ts b/src/composables/useMenuBadge.ts index 5c26c4f..42ad634 100644 --- a/src/composables/useMenuBadge.ts +++ b/src/composables/useMenuBadge.ts @@ -69,7 +69,17 @@ export function useMenuBadge() { // 处理WebSocket徽标更新消息 const handleWebSocketBadgeUpdate = (data: any) => { - // console.log('收到WebSocket徽标更新消息:', data) + // 防止重复处理 + if (data._badgeHandled) { + return + } + data._badgeHandled = true + + // 首先检查是否是数组格式的徽标数据 + if (Array.isArray(data) || (data.data && Array.isArray(data.data))) { + handleMenuBadgeDataArray(data) + return + } try { // 根据消息类型处理不同的徽标更新 @@ -98,11 +108,37 @@ export function useMenuBadge() { // 处理菜单徽标数据数组格式 const handleMenuBadgeDataArray = (data: any) => { - // console.log('收到菜单徽标数据数组:', data) + // 防止重复处理 + if (data._arrayHandled) { + return + } + data._arrayHandled = true - if (Array.isArray(data.data)) { - const updates = data.data - .filter((item: any) => item.url && typeof item.badge === 'number') + // 支持多种数据格式: + // 1. { event: '...', data: [{ url: '...', badge: 3 }] } + // 2. [{ url: '...', badge: 3 }] (直接是数组) + let badgeArray: any[] = [] + + if (Array.isArray(data)) { + // 如果 data 本身就是数组 + badgeArray = data + } else if (Array.isArray(data.data)) { + // 如果 data.data 是数组 + badgeArray = data.data + } else { + console.warn('未找到数组格式的徽标数据:', data) + return + } + + if (badgeArray.length > 0) { + const updates = badgeArray + .filter((item: any) => { + const isValid = item.url && typeof item.badge === 'number' + if (!isValid) { + console.warn('跳过无效的徽标数据项:', item) + } + return isValid + }) .map((item: any) => ({ path: item.url, count: item.badge, @@ -110,9 +146,12 @@ export function useMenuBadge() { })) if (updates.length > 0) { - // console.log('批量更新菜单徽标:', updates) batchUpdateMenuBadges(updates) + } else { + console.warn('没有有效的徽标更新项') } + } else { + console.warn('徽标数据数组为空') } } @@ -137,7 +176,11 @@ export function useMenuBadge() { // 处理审批相关的徽标更新 const handleApprovalBadgeUpdate = (data: any) => { - // console.log('收到审批徽标更新消息:', data) + // 首先检查是否是数组格式的徽标数据 + if (Array.isArray(data) || Array.isArray(data.data)) { + handleMenuBadgeDataArray(data) + return + } if (data.event === 'approval.new') { // 新审批,更新审批菜单徽标 @@ -167,7 +210,22 @@ export function useMenuBadge() { // 统一的WebSocket消息处理 const handleWebSocketMessage = (data: any) => { - if (!data || !data.event) return + if (!data) return + + // 如果已经被特定事件处理过(如 menu-badge-update),则跳过 + // 注意:_badgeProcessed 标记是在 wsClient.ts 中设置的 + if (data._badgeProcessed) { + return + } + + // 首先检查是否是数组格式的徽标数据(无论是否有 event 字段) + if (Array.isArray(data) || (data.data && Array.isArray(data.data))) { + handleMenuBadgeDataArray(data) + return + } + + // 如果没有 event 字段,无法继续处理 + if (!data.event) return // 处理菜单徽标数据数组格式(如 approval.todo.counts) if (data.event.includes('.todo.counts') || data.event.includes('.badge.counts')) { @@ -186,11 +244,9 @@ export function useMenuBadge() { // 初始化徽标系统 const initBadgeSystem = () => { if (globalInitialized) { - // console.log('菜单徽标系统已经全局初始化,跳过重复初始化') return } - // console.log('初始化菜单徽标系统') globalInitialized = true // 标记页面已加载完成 diff --git a/src/composables/useStockingForm.ts b/src/composables/useStockingForm.ts index 4dbc5fa..eed63a3 100644 --- a/src/composables/useStockingForm.ts +++ b/src/composables/useStockingForm.ts @@ -38,11 +38,11 @@ export interface BaseForm { cif_total_currency_snapshot: string is_final: string object_id: string | number - contract: string[] + contract: any[] contract_url?: string[] - pi_doc: string[] + pi_doc: any[] pi_doc_url?: string[] - transaction_slip: string[] + transaction_slip: any[] transaction_slip_url?: string[] } @@ -686,7 +686,11 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) { } contractFiles.value.push(fileInfo) // 更新合同字段为文件名数组 - baseForm.contract = contractFiles.value.map((file) => file.file_name) + baseForm.contract = contractFiles.value.map((f) => ({ + url: f.url, + original_name: f.name + })) as any + // baseForm.contract = contractFiles.value.map((file) => file.file_name) ElMessage.success('合同上传成功!') } else { ElMessage.error(response.message || '合同上传失败!') @@ -696,7 +700,11 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) { const removeContractFile = (index: number) => { contractFiles.value.splice(index, 1) // 更新合同字段为文件名数组 - baseForm.contract = contractFiles.value.map((file) => file.file_name) + baseForm.contract = contractFiles.value.map((f) => ({ + url: f.url, + original_name: f.name + })) as any + // baseForm.contract = contractFiles.value.map((file) => file.file_name) ElMessage.success('合同文件已删除') } @@ -1037,10 +1045,10 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) { : [] baseForm.contract = contractNamesArr baseForm.contract_url = contractUrlsArr - contractFiles.value = contractNamesArr.map((fileName: string, index: number) => ({ - name: fileName, + contractFiles.value = contractNamesArr.map((fileName: any, index: number) => ({ + name: fileName.original_name, url: contractUrlsArr[index] || fileName, - file_name: fileName + file_name: fileName.url })) } @@ -1056,10 +1064,10 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) { : [] baseForm.pi_doc = piNamesArr baseForm.pi_doc_url = piUrlsArr - piFiles.value = piNamesArr.map((fileName: string, index: number) => ({ - name: fileName, + piFiles.value = piNamesArr.map((fileName: any, index: number) => ({ + name: fileName.original_name, url: piUrlsArr[index] || fileName, - file_name: fileName + file_name: fileName.url })) } @@ -1075,10 +1083,10 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) { : [] baseForm.transaction_slip = slipNamesArr baseForm.transaction_slip_url = slipUrlsArr - waterBillFiles.value = slipNamesArr.map((fileName: string, index: number) => ({ - name: fileName, + waterBillFiles.value = slipNamesArr.map((fileName: any, index: number) => ({ + name: fileName.original_name, url: slipUrlsArr[index] || fileName, - file_name: fileName + file_name: fileName.url })) } // 等待本轮变更完成后,再恢复自动计算 diff --git a/src/store/modules/menuBadge.ts b/src/store/modules/menuBadge.ts index e943b95..8a25aaf 100644 --- a/src/store/modules/menuBadge.ts +++ b/src/store/modules/menuBadge.ts @@ -16,288 +16,280 @@ export interface MenuBadgeData { } // 菜单徽标Store -export const useMenuBadgeStore = defineStore( - 'menuBadgeStore', - () => { - // 徽标数据映射 - 使用普通对象而不是Map,避免持久化问题 - const badgeData = ref>({}) +export const useMenuBadgeStore = defineStore('menuBadgeStore', () => { + // 徽标数据映射 - 使用普通对象而不是Map,避免持久化问题 + const badgeData = ref>({}) - // 页面是否已加载完成 - const isPageReady = ref(false) + // 页面是否已加载完成 + const isPageReady = ref(false) - // 待处理的徽标更新队列(页面未加载完成时使用) - const pendingUpdates = ref>([]) + // 待处理的徽标更新队列(页面未加载完成时使用) + const pendingUpdates = ref>([]) - // 获取当前用户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 + } +}) diff --git a/src/utils/sys/wsClient.ts b/src/utils/sys/wsClient.ts index 217e8b7..4da4262 100644 --- a/src/utils/sys/wsClient.ts +++ b/src/utils/sys/wsClient.ts @@ -140,7 +140,7 @@ const handleMessage = (event: MessageEvent) => { isOnUserCenter = currentPath.startsWith('/admin/user/user_info') // console.warn('Router currentRoute 未初始化,使用 window.location 作为备选方案') } - } catch (error) { + } catch { // Router 完全未初始化,使用 window.location 作为备选方案 currentPath = window.location.pathname || '' isOnMobileSignature = currentPath.startsWith('/auth/signature/mobile') @@ -230,7 +230,7 @@ const handleMessage = (event: MessageEvent) => { isAlertShowing = false }) } else if (shouldShowAlert && isAlertShowing) { - console.log('当前已有弹出框显示,跳过新的提示框') + // 已有弹窗显示,避免重复弹出 } } } @@ -254,10 +254,17 @@ const handleMessage = (event: MessageEvent) => { // 处理审批相关消息 if (data.event && data.event.includes('approval')) { - // console.log('收到审批相关消息:', data) - // 如果是审批待办数量消息,直接触发徽标更新 - if (data.event.includes('.todo.counts') || data.event.includes('.badge.counts')) { + // 检查是否是数组格式的徽标数据或待办数量消息 + if ( + Array.isArray(data.data) || + Array.isArray(data) || + data.event.includes('.todo.counts') || + data.event.includes('.badge.counts') + ) { + // 数组格式的徽标数据或待办数量消息,触发菜单徽标更新事件 mittBus.emit('menu-badge-update', data) + // 标记已处理,避免在后续通用处理中重复处理 + data._badgeProcessed = true } else { // 其他审批消息触发审批徽标更新事件 mittBus.emit('approval-badge-update', data) @@ -279,10 +286,15 @@ const handleMessage = (event: MessageEvent) => { } // 处理其他可能的徽标相关消息 - if (data.event && (data.event.includes('badge') || data.event.includes('count'))) { - // console.log('收到其他徽标相关消息:', data) - // 尝试作为通用徽标更新处理 - mittBus.emit('menu-badge-update', data) + // 检查是否是数组格式的徽标数据(无论是否有 event 字段) + // 如果已经被处理过(如审批消息),则跳过 + if (!data._badgeProcessed) { + if (Array.isArray(data) || (data.data && Array.isArray(data.data))) { + mittBus.emit('menu-badge-update', data) + } else if (data.event && (data.event.includes('badge') || data.event.includes('count'))) { + // 尝试作为通用徽标更新处理 + mittBus.emit('menu-badge-update', data) + } } // 发送原始消息到事件总线 @@ -357,7 +369,6 @@ const scheduleReconnect = () => { cleanup() const delay = getReconnectDelay() - console.log(`WebSocket重连尝试 ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS},延迟: ${delay}ms`) reconnectTimer = setTimeout(() => { const { accessToken } = useUserStore() if (accessToken && !isConnecting) { diff --git a/src/views/admin/approval/approval_edit.vue b/src/views/admin/approval/approval_edit.vue index 7d1263f..24af770 100644 --- a/src/views/admin/approval/approval_edit.vue +++ b/src/views/admin/approval/approval_edit.vue @@ -638,10 +638,25 @@ if (c.type === 'initiator_leader') { group.users = [] } else if (c.value) { - group.users = String(c.value) + // group.users = String(c.value) + // .split(',') + // .map((v) => Number((v || '').trim())) + // .filter((n) => !Number.isNaN(n)) + const values = String(c.value) .split(',') - .map((v) => Number((v || '').trim())) - .filter((n) => !Number.isNaN(n)) + .map((v) => (v || '').trim()) + .filter(Boolean) + // 判断是否为纯数字ID + const isNumericIds = values.every( + (v) => !Number.isNaN(Number(v)) && Number.isInteger(Number(v)) + ) + if (isNumericIds) { + // 如果是数字ID,转换为数字数组 + group.users = values.map((v) => Number(v)) + } else { + // 如果是字符串名称,保持为字符串数组 + group.users = values + } } node.ccGroups.push(group) } diff --git a/src/views/admin/approval/stocking_auth_detil.vue b/src/views/admin/approval/stocking_auth_detil.vue index 1d7a29c..9ca5821 100644 --- a/src/views/admin/approval/stocking_auth_detil.vue +++ b/src/views/admin/approval/stocking_auth_detil.vue @@ -242,7 +242,7 @@ const processFiles = (files: any[], type: string) => { if (!files || !Array.isArray(files)) return [] return files.map((file: any) => ({ - name: `${type}文件`, + name: file.original_name, url: file.file_full_url || file.file_url, file_name: file.file_url })) diff --git a/src/views/admin/procurement/purchase_order.vue b/src/views/admin/procurement/purchase_order.vue index 1bbe565..0392079 100644 --- a/src/views/admin/procurement/purchase_order.vue +++ b/src/views/admin/procurement/purchase_order.vue @@ -937,6 +937,8 @@ pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted', comment: h?.comment || h?.remark || '' })) + } else { + approvalRecords.value = [] } timelineDialogVisible.value = true } diff --git a/src/views/admin/stock/final_list_admin.vue b/src/views/admin/stock/final_list_admin.vue index cfff00c..194567a 100644 --- a/src/views/admin/stock/final_list_admin.vue +++ b/src/views/admin/stock/final_list_admin.vue @@ -335,7 +335,7 @@ const processFiles = (files: any[], type: string) => { if (!files || !Array.isArray(files)) return [] return files.map((file: any) => ({ - name: `${type}文件`, + name: file.original_name, url: file.file_full_url || file.file_url, file_name: file.file_url })) @@ -499,6 +499,8 @@ pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted', comment: h?.comment || h?.remark || '' })) + } else { + approvalRecords.value = [] } timelineDialogVisible.value = true } diff --git a/src/views/admin/stock/stocking_list_admin.vue b/src/views/admin/stock/stocking_list_admin.vue index f35171e..477a82f 100644 --- a/src/views/admin/stock/stocking_list_admin.vue +++ b/src/views/admin/stock/stocking_list_admin.vue @@ -275,7 +275,7 @@ const processFiles = (files: any[], type: string) => { if (!files || !Array.isArray(files)) return [] return files.map((file: any) => ({ - name: `${type}文件`, + name: file.original_name, url: file.file_full_url || file.file_url, file_name: file.file_url })) @@ -499,6 +499,8 @@ pending: h?.status != 'approved' && h?.status != 'rejected' && h?.status != 'submitted', comment: h?.comment || h?.remark || '' })) + } else { + approvalRecords.value = [] } timelineDialogVisible.value = true } diff --git a/src/views/admin/user/index.vue b/src/views/admin/user/index.vue index 92c8e68..e81fe5d 100644 --- a/src/views/admin/user/index.vue +++ b/src/views/admin/user/index.vue @@ -60,6 +60,7 @@ +