新增退款待审核角标提醒
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import type { RouteLocationNormalizedLoaded } from 'vue-router'
|
||||
|
||||
import { fetchPendingRefundCount } from '@/features/orders/api/orders'
|
||||
import { useAdminSessionStore } from '@/stores/adminSession'
|
||||
|
||||
export const pendingRefundCountChangedEvent = 'pending-refund-count-changed'
|
||||
|
||||
export function usePendingRefundCount(route: RouteLocationNormalizedLoaded) {
|
||||
const adminSession = useAdminSessionStore()
|
||||
const count = ref(0)
|
||||
let timer: number | null = null
|
||||
let requestID = 0
|
||||
|
||||
const label = computed(() => (count.value > 99 ? '99+' : String(count.value)))
|
||||
const canReviewRefund = computed(
|
||||
() => adminSession.isSuperAdmin || adminSession.hasPermission('order:close')
|
||||
)
|
||||
|
||||
function stopPolling() {
|
||||
if (timer === null) return
|
||||
window.clearInterval(timer)
|
||||
timer = null
|
||||
}
|
||||
|
||||
async function refresh() {
|
||||
if (!canReviewRefund.value) {
|
||||
count.value = 0
|
||||
return
|
||||
}
|
||||
const currentID = ++requestID
|
||||
try {
|
||||
const nextCount = await fetchPendingRefundCount()
|
||||
if (currentID === requestID) count.value = nextCount
|
||||
} catch {
|
||||
// 角标加载失败时保持当前数字,避免影响后台其他操作。
|
||||
}
|
||||
}
|
||||
|
||||
function startPolling() {
|
||||
stopPolling()
|
||||
void refresh()
|
||||
timer = window.setInterval(refresh, 30_000)
|
||||
}
|
||||
|
||||
function handleVisibilityChange() {
|
||||
if (document.hidden) {
|
||||
stopPolling()
|
||||
return
|
||||
}
|
||||
startPolling()
|
||||
}
|
||||
|
||||
function handleCountChanged() {
|
||||
void refresh()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
window.addEventListener(pendingRefundCountChangedEvent, handleCountChanged)
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange)
|
||||
if (!document.hidden) startPolling()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopPolling()
|
||||
window.removeEventListener(pendingRefundCountChangedEvent, handleCountChanged)
|
||||
document.removeEventListener('visibilitychange', handleVisibilityChange)
|
||||
})
|
||||
|
||||
watch(canReviewRefund, canReview => {
|
||||
if (canReview && !document.hidden) {
|
||||
startPolling()
|
||||
return
|
||||
}
|
||||
stopPolling()
|
||||
count.value = 0
|
||||
})
|
||||
|
||||
watch(
|
||||
() => route.fullPath,
|
||||
() => void refresh()
|
||||
)
|
||||
|
||||
return {
|
||||
pendingRefundCount: count,
|
||||
pendingRefundLabel: label,
|
||||
refreshPendingRefundCount: refresh,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user