fix(documents): move unread notice into bell
This commit is contained in:
@@ -138,7 +138,10 @@
|
||||
|
||||
<div v-if="notificationOpen" class="notification-popover" role="dialog" aria-label="通知中心">
|
||||
<header class="notification-head">
|
||||
<strong>通知</strong>
|
||||
<span class="notification-head-copy">
|
||||
<strong>通知中心</strong>
|
||||
<small>{{ unreadNotifications.length ? `${unreadNotifications.length} 条待处理` : '暂无待处理通知' }}</small>
|
||||
</span>
|
||||
<button type="button" aria-label="关闭通知" @click="notificationOpen = false">
|
||||
<i class="mdi mdi-close"></i>
|
||||
</button>
|
||||
@@ -152,7 +155,8 @@
|
||||
:class="{ active: notificationTab === 'unread' }"
|
||||
@click="notificationTab = 'unread'"
|
||||
>
|
||||
未读 {{ unreadNotifications.length }}
|
||||
<span>未读</span>
|
||||
<em>{{ unreadNotifications.length }}</em>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@@ -161,7 +165,8 @@
|
||||
:class="{ active: notificationTab === 'read' }"
|
||||
@click="notificationTab = 'read'"
|
||||
>
|
||||
已读 {{ readNotifications.length }}
|
||||
<span>已读</span>
|
||||
<em>{{ readNotifications.length }}</em>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -173,11 +178,19 @@
|
||||
class="notification-row"
|
||||
@click="openNotification(item)"
|
||||
>
|
||||
<span class="notification-dot" :class="item.tone"></span>
|
||||
<span class="notification-type-icon" :class="item.tone">
|
||||
<i :class="resolveNotificationIcon(item)"></i>
|
||||
</span>
|
||||
<span class="notification-copy">
|
||||
<strong>{{ item.title }}</strong>
|
||||
<span class="notification-title-line">
|
||||
<strong>{{ item.title }}</strong>
|
||||
<b v-if="item.badge">{{ item.badge }}</b>
|
||||
</span>
|
||||
<small>{{ item.description }}</small>
|
||||
<em>{{ item.time }}</em>
|
||||
<span class="notification-meta">
|
||||
<em>{{ item.category || '系统通知' }}</em>
|
||||
<time>{{ item.time }}</time>
|
||||
</span>
|
||||
</span>
|
||||
<i class="mdi mdi-chevron-right"></i>
|
||||
</button>
|
||||
@@ -274,8 +287,9 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
import { useDocumentCenterInbox } from '../../composables/useDocumentCenterInbox.js'
|
||||
import EnterpriseSelect from '../shared/EnterpriseSelect.vue'
|
||||
|
||||
const props = defineProps({
|
||||
@@ -342,7 +356,8 @@ const emit = defineEmits([
|
||||
'batchApprove',
|
||||
'openChat',
|
||||
'newApplication',
|
||||
'openDocument'
|
||||
'openDocument',
|
||||
'navigate'
|
||||
])
|
||||
const isChat = computed(() => props.activeView === 'chat')
|
||||
const isOverview = computed(() => props.activeView === 'overview')
|
||||
@@ -359,27 +374,111 @@ const eyebrowLabel = computed(() => (
|
||||
|| (isChat.value ? 'Smart Finance Q&A' : 'Smart Expense Operations')
|
||||
))
|
||||
const displayCompanyName = computed(() => String(props.companyName || '远光软件股份有限公司').trim() || '远光软件股份有限公司')
|
||||
const topbarNotificationCount = computed(() => {
|
||||
const {
|
||||
refreshDocumentInbox,
|
||||
startDocumentInboxPolling,
|
||||
stopDocumentInboxPolling,
|
||||
unreadCount: documentInboxUnreadCount
|
||||
} = useDocumentCenterInbox()
|
||||
let documentInboxInitialRefreshTimer = null
|
||||
const workbenchNotificationCount = computed(() => {
|
||||
const summary = props.workbenchSummary ?? {}
|
||||
const count = Number(summary.unreadNotificationCount ?? 0)
|
||||
return Number.isFinite(count) && count > 0 ? count : 0
|
||||
})
|
||||
const topbarNotificationCount = computed(() => {
|
||||
const count = workbenchNotificationCount.value + Number(documentInboxUnreadCount.value || 0)
|
||||
return Number.isFinite(count) && count > 0 ? Math.min(count, 99) : 0
|
||||
})
|
||||
const notificationOpen = ref(false)
|
||||
const notificationTab = ref('unread')
|
||||
const notificationItems = computed(() => (
|
||||
const documentInboxBadgeText = computed(() => {
|
||||
const count = Number(documentInboxUnreadCount.value || 0)
|
||||
return count > 99 ? '99+' : String(count)
|
||||
})
|
||||
const documentInboxNotification = computed(() => {
|
||||
const count = Number(documentInboxUnreadCount.value || 0)
|
||||
if (!Number.isFinite(count) || count <= 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
return {
|
||||
id: 'document-center-unread',
|
||||
title: '单据中心有新单据',
|
||||
description: `当前有 ${count} 条新单据待查看`,
|
||||
time: '刚刚更新',
|
||||
category: '单据中心',
|
||||
tone: 'danger',
|
||||
unread: true,
|
||||
icon: 'mdi mdi-file-document-alert-outline',
|
||||
badge: documentInboxBadgeText.value,
|
||||
target: { type: 'documents-center' }
|
||||
}
|
||||
})
|
||||
const workbenchNotificationItems = computed(() => (
|
||||
Array.isArray(props.workbenchSummary?.notifications)
|
||||
? props.workbenchSummary.notifications
|
||||
: []
|
||||
))
|
||||
const notificationItems = computed(() => {
|
||||
const inboxNotification = documentInboxNotification.value
|
||||
return inboxNotification
|
||||
? [inboxNotification, ...workbenchNotificationItems.value]
|
||||
: workbenchNotificationItems.value
|
||||
})
|
||||
const unreadNotifications = computed(() => notificationItems.value.filter((item) => item.unread))
|
||||
const readNotifications = computed(() => notificationItems.value.filter((item) => !item.unread))
|
||||
const activeNotifications = computed(() => (
|
||||
notificationTab.value === 'unread' ? unreadNotifications.value : readNotifications.value
|
||||
))
|
||||
|
||||
function clearDocumentInboxInitialRefreshTimer() {
|
||||
if (documentInboxInitialRefreshTimer && typeof window !== 'undefined') {
|
||||
window.clearTimeout(documentInboxInitialRefreshTimer)
|
||||
documentInboxInitialRefreshTimer = null
|
||||
}
|
||||
}
|
||||
|
||||
function scheduleDocumentInboxInitialRefresh() {
|
||||
if (typeof window === 'undefined') {
|
||||
return
|
||||
}
|
||||
|
||||
clearDocumentInboxInitialRefreshTimer()
|
||||
documentInboxInitialRefreshTimer = window.setTimeout(() => {
|
||||
documentInboxInitialRefreshTimer = null
|
||||
void refreshDocumentInbox()
|
||||
}, props.activeView === 'workbench' ? 1200 : 6000)
|
||||
}
|
||||
|
||||
function resolveNotificationIcon(item) {
|
||||
if (item?.icon) {
|
||||
return item.icon
|
||||
}
|
||||
|
||||
if (item?.tone === 'danger') {
|
||||
return 'mdi mdi-alert-circle-outline'
|
||||
}
|
||||
|
||||
if (item?.tone === 'warning') {
|
||||
return 'mdi mdi-alert-outline'
|
||||
}
|
||||
|
||||
if (item?.tone === 'success') {
|
||||
return 'mdi mdi-check-circle-outline'
|
||||
}
|
||||
|
||||
return 'mdi mdi-bell-outline'
|
||||
}
|
||||
|
||||
function openNotification(item) {
|
||||
notificationOpen.value = false
|
||||
const target = item?.target || {}
|
||||
if (target.type === 'documents-center') {
|
||||
emit('navigate', 'documents')
|
||||
return
|
||||
}
|
||||
|
||||
if (target.type === 'document' && (target.id || target.claimNo)) {
|
||||
emit('openDocument', {
|
||||
claimId: target.id,
|
||||
@@ -566,16 +665,36 @@ const canApplyCustomRange = computed(() =>
|
||||
Boolean(draftStart.value && draftEnd.value && draftStart.value <= draftEnd.value)
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.customRange,
|
||||
(range) => {
|
||||
draftStart.value = range.start
|
||||
draftEnd.value = range.end
|
||||
watch(
|
||||
() => props.customRange,
|
||||
(range) => {
|
||||
draftStart.value = range.start
|
||||
draftEnd.value = range.end
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
function setRange(range) {
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.activeView,
|
||||
(activeView, previousView) => {
|
||||
if (activeView === 'workbench' && previousView !== 'workbench') {
|
||||
clearDocumentInboxInitialRefreshTimer()
|
||||
void refreshDocumentInbox({ force: true })
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
scheduleDocumentInboxInitialRefresh()
|
||||
startDocumentInboxPolling()
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
clearDocumentInboxInitialRefreshTimer()
|
||||
stopDocumentInboxPolling()
|
||||
})
|
||||
|
||||
function setRange(range) {
|
||||
emit('update:activeRange', range)
|
||||
calendarOpen.value = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user