refactor: extract image form to standalone page and implement tags view store
- Created ImageForm.vue as standalone page for add/edit image functionality - Removed dialog-based image form from VmImages.vue - Implemented tagsViewStore for global tab state management - Added automatic tab closing on form cancel/back - Fixed data persistence issue when switching between image edits - Removed quick actions section from ImageForm - Updated router configuration for new image form route
This commit is contained in:
@@ -336,9 +336,24 @@ const fetchTicketList = async (append = false) => {
|
||||
}))
|
||||
|
||||
if (append) {
|
||||
ticketList.value = [...ticketList.value, ...mappedTickets]
|
||||
// 翻页时:合并列表,使用work_id去重,然后按work_id从大到小排序
|
||||
const existingIds = new Set(ticketList.value.map(t => t.id))
|
||||
const newTickets = mappedTickets.filter(t => !existingIds.has(t.id))
|
||||
const mergedTickets = [...ticketList.value, ...newTickets]
|
||||
|
||||
// 按work_id从大到小排序
|
||||
ticketList.value = mergedTickets.sort((a, b) => {
|
||||
const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
|
||||
const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
|
||||
return idB - idA
|
||||
})
|
||||
} else {
|
||||
ticketList.value = mappedTickets
|
||||
// 首次加载或切换类别:直接使用新数据,按work_id从大到小排序
|
||||
ticketList.value = mappedTickets.sort((a, b) => {
|
||||
const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
|
||||
const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
|
||||
return idB - idA
|
||||
})
|
||||
}
|
||||
|
||||
hasMore.value = ticketList.value.length < res.data.all_count
|
||||
@@ -398,6 +413,18 @@ const fetchAllStats = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 只刷新当前分类的统计数据(用于定时刷新,减少请求)
|
||||
const fetchCurrentStatusStat = async () => {
|
||||
try {
|
||||
// 只获取当前选中分类的统计数据
|
||||
await fetchStatusStat(activeStatus.value)
|
||||
// 同时获取全部工单数量(因为顶部显示需要)
|
||||
await fetchStatusStat('')
|
||||
} catch (error) {
|
||||
console.error('获取当前分类统计数据出错:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载更多工单
|
||||
const loadMoreTickets = () => {
|
||||
if (!hasMore.value || isLoading.value) return
|
||||
@@ -436,16 +463,16 @@ const filteredTickets = computed(() => {
|
||||
)
|
||||
}
|
||||
|
||||
// 按最后回复时间排序(优先显示有新消息的)
|
||||
// 按work_id从大到小排序(优先显示待处理)
|
||||
return result.sort((a, b) => {
|
||||
// 优先显示待处理
|
||||
if (a.status === 'pending' && b.status !== 'pending') return -1
|
||||
if (a.status !== 'pending' && b.status === 'pending') return 1
|
||||
|
||||
// 然后按最后回复时间
|
||||
const timeA = new Date(a.lastReplyTime || a.createTime)
|
||||
const timeB = new Date(b.lastReplyTime || b.createTime)
|
||||
return timeB - timeA
|
||||
// 然后按work_id从大到小排序
|
||||
const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
|
||||
const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
|
||||
return idB - idA
|
||||
})
|
||||
})
|
||||
|
||||
@@ -685,7 +712,8 @@ const filterByStatus = (status) => {
|
||||
activeStatus.value = status
|
||||
currentPage.value = 1 // 切换状态后重置页码
|
||||
hasMore.value = true // 重置加载更多标志
|
||||
fetchTicketList() // 重新获取数据
|
||||
ticketList.value = [] // 清空列表,不缓存
|
||||
fetchTicketList(false) // 从头重新获取数据,不追加
|
||||
}
|
||||
|
||||
// 搜索处理
|
||||
@@ -775,8 +803,8 @@ const startAutoRefresh = () => {
|
||||
// 静默刷新工单列表,保持当前页码
|
||||
refreshTicketList()
|
||||
|
||||
// 刷新工单统计
|
||||
fetchAllStats()
|
||||
// 只刷新当前分类的统计数据,减少请求数量
|
||||
fetchCurrentStatusStat()
|
||||
}, refreshInterval)
|
||||
}
|
||||
|
||||
@@ -800,7 +828,8 @@ const refreshTicketList = async () => {
|
||||
else if (activeStatus.value === 'completed') statusParam = '3'
|
||||
}
|
||||
|
||||
const res = await getTickerList(pageSize.value, currentPage.value, statusParam)
|
||||
// 刷新时只获取第一页数据,用于更新最新数据
|
||||
const res = await getTickerList(pageSize.value, 1, statusParam)
|
||||
|
||||
if (res.code === 200) {
|
||||
const tickets = res.data.data || []
|
||||
@@ -817,8 +846,27 @@ const refreshTicketList = async () => {
|
||||
content: item.name
|
||||
}))
|
||||
|
||||
// 更新列表
|
||||
ticketList.value = mappedTickets
|
||||
// 合并到现有列表,去重并按work_id从大到小排序
|
||||
// 使用Map来更新已存在的工单信息,添加新的工单
|
||||
const ticketMap = new Map()
|
||||
// 先添加现有列表
|
||||
ticketList.value.forEach(ticket => {
|
||||
ticketMap.set(ticket.id, ticket)
|
||||
})
|
||||
// 更新或添加新数据(新数据会覆盖旧数据)
|
||||
mappedTickets.forEach(ticket => {
|
||||
ticketMap.set(ticket.id, ticket)
|
||||
})
|
||||
|
||||
// 转换为数组并按work_id从大到小排序
|
||||
ticketList.value = Array.from(ticketMap.values()).sort((a, b) => {
|
||||
const idA = typeof a.id === 'string' ? parseInt(a.id) || 0 : a.id
|
||||
const idB = typeof b.id === 'string' ? parseInt(b.id) || 0 : b.id
|
||||
return idB - idA
|
||||
})
|
||||
|
||||
// 不重置页码,保持用户当前的浏览位置
|
||||
// 更新加载更多标志
|
||||
hasMore.value = ticketList.value.length < res.data.all_count
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user