通知系統完整指南
最後更新: 2025-10-07 業務重要性: ⭐⭐⭐ (通知系統)
系統概述
通知系統是後台管理系統的核心功能之一,專為內部員工工作協作與業務處理需求設計。
系統範圍
- ✅ 包含範圍: 內部員工工作通知、系統監控警報、業務流程通知
- ❌ 不包含範圍: 客戶端通知、行銷推播、外部系統通知
用戶對象
- 主要用戶: 內部員工(管理員、銷售、客服、倉庫、IT等)
- 次要用戶: 系統管理員、開發人員
系統架構
整體架構圖
┌─────────────────────────────────────────────────────────┐
│ 通知系統架構 │
├─────────────────────────────────────────────────────────┤
│ 前端 UI 層 │
│ ├─ NotificationList.vue (通知列表) │
│ ├─ NotificationCard.vue (通知卡片) │
│ ├─ NotificationBadge.vue (通知徽章) │
│ └─ GroupNotificationCard.vue (群組通知) │
├─────────────────────────────────────────────────────────┤
│ 業務邏輯層 │
│ ├─ useNotification.ts (Vue Composable) │
│ ├─ NotificationApiService.ts (API 服務) │
│ └─ GroupNotificationApiService.ts (群組通知服務) │
├─────────────────────────────────────────────────────────┤
│ 資料處理層 │
│ ├─ notification-helpers.ts (業務邏輯輔助) │
│ ├─ notification-validators.ts (資料驗證) │
│ └─ notification-type-monitoring.ts (類型監控) │
├─────────────────────────────────────────────────────────┤
│ 資料庫層 │
│ ├─ notifications (核心通知表) │
│ ├─ notification_templates (通知模板) │
│ ├─ notification_groups (群組定義) │
│ └─ notification_recipients (接收者記錄) │
└─────────────────────────────────────────────────────────┘核心功能
1. 通知分類系統
- INFORMATIONAL: 資訊性通知(僅通知,無需操作)
- ACTIONABLE: 可操作通知(需要用戶響應)
2. 完成策略系統
- AUTO: 自動完成(系統自動標記完成)
- SUGGESTED: 建議完成(系統提供建議)
- MANUAL: 手動完成(用戶手動標記)
3. 群組通知機制
- ROLE: 基於角色的通知
- DEPARTMENT: 基於部門的通知
- BROADCAST: 廣播通知(全體)
前端實現
Vue 組件使用
NotificationBadge 組件
vue
<template>
<NotificationBadge
:userId="currentUser.id"
:autoRefresh="true"
:refreshInterval="60000"
/>
</template>
<script setup>
import { NotificationBadge } from '@/components/notify/NotificationBadge.vue'
import { useAuth } from '@/composables/useAuth'
const { currentUser } = useAuth()
</script>NotificationList 組件
vue
<template>
<NotificationList
:userId="userId"
:limit="10"
:showActions="true"
@notification-read="handleRead"
@notification-completed="handleCompleted"
/>
</template>Composable 使用
useNotification
typescript
import { useNotification } from '@/composables/useNotification'
const userId = ref('user-123')
const {
notifications,
unreadCount,
subscribeToNotifications,
unsubscribeFromNotifications,
markAsRead,
markAsCompleted,
isRealtimeConnected,
realtimeError,
} = useNotification(userId)
// 啟動 realtime 訂閱
subscribeToNotifications()API 服務層
NotificationApiService
基本操作
typescript
import { NotificationApiService } from '@/api/services'
// 獲取通知列表
const notifications = await NotificationApiService.getNotifications({
userId: 'user-123',
limit: 10,
offset: 0
})
// 標記已讀
await NotificationApiService.markAsRead('notification-id')
// 標記完成
await NotificationApiService.markAsCompleted('notification-id')
// 創建通知
await NotificationApiService.createNotification({
type: 'order_new',
title: '新訂單通知',
message: '收到新訂單 #12345',
userId: 'user-123',
relatedEntityId: 'order-12345',
relatedEntityType: 'order'
})GroupNotificationApiService
群組通知操作
typescript
import { GroupNotificationApiService } from '@/api/services'
// 創建群組通知
await GroupNotificationApiService.createGroupNotification({
type: 'system_maintenance',
title: '系統維護通知',
message: '系統將於今晚進行維護',
groupType: 'role',
groupValue: 'admin',
scheduledFor: new Date('2024-01-20 22:00:00')
})
// 獲取群組通知狀態
const status = await GroupNotificationApiService.getGroupNotificationStatus('group-notification-id')輔助函數庫
notification-helpers.ts
業務邏輯輔助函數
typescript
import {
getTemplateByType,
getNotificationCategoryFromTemplate,
getCompletionStrategyFromTemplate,
isActionableNotificationFromTemplate
} from '@/lib/notification-helpers'
// 獲取通知模板
const template = getTemplateByType(templates, NotificationType.ORDER_NEW)
// 獲取通知分類
const category = getNotificationCategoryFromTemplate(templates, type)
// 返回: 'informational' | 'actionable' | undefined
// 檢查是否為可操作通知
const isActionable = isActionableNotificationFromTemplate(templates, type)notification-validators.ts
資料驗證函數
typescript
import {
validateNotificationData,
validateNotificationTemplate,
validateCompletionData
} from '@/lib/notification-validators'
// 驗證通知資料完整性
const isValid = validateNotificationData(notificationData)
// 驗證模板配置
const templateValid = validateNotificationTemplate(template)類型系統
核心類型定義
typescript
// 通知類型枚舉
export enum NotificationType {
ORDER_NEW = 'order_new',
ORDER_HIGH_VALUE = 'order_high_value',
INVENTORY_LOW_STOCK = 'inventory_low_stock',
CUSTOMER_SERVICE_NEW_REQUEST = 'customer_service_new_request',
SECURITY_PERMISSION_CHANGED = 'security_permission_changed'
}
// 混合類型支援
export type NotificationTypeValue = NotificationType | string
// 通知介面
export interface NotificationData {
id: string
type: NotificationTypeValue
title: string
message: string
category: 'informational' | 'actionable'
status: 'unread' | 'read' | 'completed'
userId: string
createdAt: Date
relatedEntityId?: string
relatedEntityType?: RelatedEntityType
}類型選擇策略
使用核心類型 (推薦)
typescript
// ✅ 推薦:使用預定義類型
const notification = {
type: NotificationType.ORDER_NEW, // 強類型,IDE 支援
title: '新訂單通知'
}使用動態類型 (特殊情況)
typescript
// ⚠️ 特殊情況:動態類型
const customNotification = {
type: 'custom_event_2024', // 字串類型,彈性更高
title: '自定義事件'
}🔄 Real-time 功能
Supabase Realtime 整合
typescript
// 啟動即時通知訂閱
const { subscribeToNotifications } = useNotification(userId)
// 監控連線狀態
watch(isRealtimeConnected, (connected) => {
if (connected) {
console.log('✅ Realtime 連線成功')
} else {
console.log('❌ Realtime 連線失敗,啟動輪詢備援')
startPolling(60000)
}
})Hybrid 模式
系統採用 Realtime + 輪詢的混合模式:
- 主要模式: Realtime 即時推播
- 備援模式: 輪詢機制(60秒間隔)
- 容錯機制: 自動切換和重連
資料庫結構
核心表格
notifications 表
sql
CREATE TABLE notifications (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
type VARCHAR(100) NOT NULL,
title TEXT NOT NULL,
message TEXT NOT NULL,
category notification_category NOT NULL,
status notification_status NOT NULL DEFAULT 'unread',
user_id UUID NOT NULL REFERENCES users(id),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
related_entity_id VARCHAR(255),
related_entity_type related_entity_type
);notification_templates 表
sql
CREATE TABLE notification_templates (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
type VARCHAR(100) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
category notification_category NOT NULL,
completion_strategy completion_strategy NOT NULL,
required_entity_type related_entity_type,
is_active BOOLEAN DEFAULT true
);權限設定 (RLS)
sql
-- 用戶只能看到自己的通知
CREATE POLICY "Users can view their own notifications" ON notifications
FOR SELECT USING (user_id = auth.uid());
-- 管理員可以創建通知
CREATE POLICY "Admins can create notifications" ON notifications
FOR INSERT WITH CHECK (
EXISTS (
SELECT 1 FROM user_roles
WHERE user_id = auth.uid()
AND role_name IN ('admin', 'system')
)
);🧪 測試策略
組件測試
NotificationCard 測試
typescript
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import NotificationCard from '@/components/notify/NotificationCard.vue'
describe('NotificationCard', () => {
it('should display notification content correctly', () => {
const notification = {
id: '1',
title: '測試通知',
message: '這是測試訊息',
status: 'unread'
}
const wrapper = mount(NotificationCard, {
props: { notification }
})
expect(wrapper.text()).toContain('測試通知')
expect(wrapper.text()).toContain('這是測試訊息')
})
})API 測試
typescript
describe('NotificationApiService', () => {
it('should fetch notifications correctly', async () => {
const notifications = await NotificationApiService.getNotifications({
userId: 'test-user',
limit: 5
})
expect(notifications).toBeDefined()
expect(notifications.length).toBeLessThanOrEqual(5)
})
})部署指南
環境變數設定
env
# Supabase 配置
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-anon-key
# 通知系統配置
VITE_NOTIFICATION_REFRESH_INTERVAL=30000
VITE_MAX_NOTIFICATIONS_PER_PAGE=20
VITE_ENABLE_REAL_TIME_NOTIFICATIONS=true資料庫部署
bash
# 執行通知系統 SQL 遷移
cd notify-sql
psql -h your-db-host -U postgres -d postgres -f 01_notifications_core_schema.sql
psql -h your-db-host -U postgres -d postgres -f 02_notifications_initial_data.sql
# ... 其他 SQL 文件📈 監控與除錯
效能監控
typescript
import { notificationPerformanceMonitor } from '@/utils/performance'
// 取得效能報告
const report = notificationPerformanceMonitor.getPerformanceReport()
console.log('通知系統效能:', report)除錯模式
typescript
// 啟用 console 日誌追蹤
console.log('🔔 Notification channel status:', status)
console.log('💡 Suggestion channel status:', status)🔍 故障排除
常見問題
通知不顯示
- 檢查 Supabase 連接設定
- 確認 RLS 政策正確
- 驗證用戶權限
即時通知失效
- 檢查 WebSocket 連線狀態
- 確認防火牆設定
- 啟用輪詢備援機制
效能問題
- 檢查通知數量限制
- 優化資料庫查詢
- 啟用快取機制
相關文檔
最後更新: $(date "+%Y-%m-%d")版本: 2.0