refactor: improve SSE connection handling and clean up notification component

This commit is contained in:
Jacky 2025-04-28 03:40:36 +00:00
parent 5aaf8cc36f
commit a39ec77992
No known key found for this signature in database
GPG key ID: 215C21B10DF38B4D
6 changed files with 24 additions and 38 deletions

View file

@ -1,17 +1,16 @@
<script setup lang="ts">
import type { Notification } from '@/api/notification'
import type { CustomRender } from '@/components/StdDesign/StdDataDisplay/StdTableTransformer'
import type { SSEvent } from 'sse.js'
import type { Ref } from 'vue'
import notificationApi from '@/api/notification'
import { detailRender } from '@/components/Notification/detailRender'
import { useSSE } from '@/composables/useSSE'
import { NotificationTypeT } from '@/constants'
import { useUserStore } from '@/pinia'
import { BellOutlined, CheckCircleOutlined, CloseCircleOutlined, DeleteOutlined, InfoCircleOutlined, WarningOutlined } from '@ant-design/icons-vue'
import { message, notification } from 'ant-design-vue'
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import { SSE } from 'sse.js'
import notifications from './notifications'
defineProps<{
@ -22,32 +21,15 @@ dayjs.extend(relativeTime)
const loading = ref(false)
const { token, unreadCount } = storeToRefs(useUserStore())
const { unreadCount } = storeToRefs(useUserStore())
const data = ref([]) as Ref<Notification[]>
const sse = shallowRef(newSSE())
function reconnect() {
setTimeout(() => {
sse.value = newSSE()
}, 5000)
}
function newSSE() {
const s = new SSE('api/notifications/live', {
headers: {
Authorization: token.value,
},
})
s.onmessage = (e: SSEvent) => {
const data = JSON.parse(e.data)
// data.type may be 0
if (data.type === undefined || data.type === null || data.type === '') {
return
}
const { connect } = useSSE()
connect({
url: '/api/notifications/live',
onMessage: (data: Notification) => {
const typeTrans = {
0: 'error',
1: 'warning',
@ -59,13 +41,8 @@ function newSSE() {
message: $gettext(data.title),
description: detailRender({ text: data.details, record: data } as CustomRender),
})
}
// reconnect
s.onerror = reconnect
return s
}
},
})
function init() {
loading.value = true

View file

@ -6,7 +6,6 @@ import frontendTasks from './tasks/frontend'
export const useSelfCheckStore = defineStore('selfCheck', () => {
const data = ref<TaskReport[]>([])
const requestError = ref(false)
const loading = ref(false)
async function __check() {
@ -42,7 +41,6 @@ export const useSelfCheckStore = defineStore('selfCheck', () => {
}
catch (error) {
console.error(error)
requestError.value = true
}
finally {
loading.value = false
@ -72,7 +70,7 @@ export const useSelfCheckStore = defineStore('selfCheck', () => {
}
const hasError = computed(() => {
return requestError.value || data.value?.some(item => item.status === ReportStatus.Error)
return data.value?.some(item => item.status === ReportStatus.Error)
})
return { data, loading, fixing, hasError, check, fix }

View file

@ -25,7 +25,9 @@ export function useSSE() {
* Connect to SSE service
*/
function connect(options: SSEOptions) {
disconnect()
if (token.value) {
return
}
const {
url,

View file

@ -1,7 +1,7 @@
<script setup lang="ts">
import settings from '@/api/settings'
import PageHeader from '@/components/PageHeader/PageHeader.vue'
import { useSettingsStore } from '@/pinia'
import { useSettingsStore, useUserStore } from '@/pinia'
import { throttle } from 'lodash'
import { storeToRefs } from 'pinia'
import FooterLayout from './FooterLayout.vue'
@ -44,10 +44,13 @@ settings.get_server_name().then(r => {
const breadList = ref([])
provide('breadList', breadList)
const userStore = useUserStore()
const { token } = storeToRefs(userStore)
</script>
<template>
<ALayout class="full-screen-wrapper min-h-screen">
<ALayout :key="token" class="full-screen-wrapper min-h-screen">
<div class="drawer-sidebar">
<ADrawer
v-model:open="drawerVisible"

View file

@ -131,7 +131,7 @@ export function setupResponseInterceptor() {
case 403:
user.logout()
await router.push('/login')
break
return
}
}

View file

@ -1,6 +1,7 @@
<script setup lang="tsx">
import cert from '@/api/cert'
import StdTable from '@/components/StdDesign/StdDataDisplay/StdTable.vue'
import { useGlobalStore } from '@/pinia'
import { CloudUploadOutlined, SafetyCertificateOutlined } from '@ant-design/icons-vue'
import RemoveCert from '../components/RemoveCert.vue'
import WildcardCertificate from '../components/WildcardCertificate.vue'
@ -8,6 +9,10 @@ import certColumns from './certColumns'
const refWildcard = ref()
const refTable = ref()
const globalStore = useGlobalStore()
const { processingStatus } = storeToRefs(globalStore)
</script>
<template>
@ -25,6 +30,7 @@ const refTable = ref()
<AButton
type="link"
size="small"
:disabled="processingStatus.auto_cert_processing"
@click="() => refWildcard.open()"
>
<SafetyCertificateOutlined />