Giao diện
Cấu hình chi tiết — In-App Message
Database Schema
Thông báo in-app được lưu trong collection messages (quản lý bởi notification-manager):
| Trường | Kiểu | Mô tả |
|---|---|---|
id | bigint (PK) | ID thông báo |
userId | bigint | ID người nhận |
title | string | Tiêu đề thông báo |
content | json | Nội dung chi tiết (hỗ trợ rich content) |
read | boolean | Trạng thái đã đọc (mặc định: false) |
channelName | string | Tên kênh đã gửi |
createdAt | datetime | Thời gian tạo |
Cấu trúc content
Trường content là JSON linh hoạt, hỗ trợ nhiều loại nội dung:
json
{
"text": "Bạn có đơn hàng mới #1234",
"link": "/orders/1234",
"metadata": {
"orderId": 1234,
"status": "new"
}
}Cấu hình SSE
| Tham số | Giá trị | Mô tả |
|---|---|---|
| Keepalive interval | ~30 giây | Gửi comment SSE để giữ kết nối |
| Reconnect | Tự động | Trình duyệt tự reconnect khi mất kết nối |
| Event type | message | Loại SSE event mặc định |
Cấu hình Nginx cho SSE
Nếu dùng Nginx làm reverse proxy, cần thêm cấu hình cho endpoint SSE:
nginx
location /api/sse {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 86400s;
chunked_transfer_encoding off;
}Quan trọng
Nếu không tắt proxy_buffering, Nginx sẽ buffer SSE response và thông báo không real-time — người dùng phải đợi buffer đầy hoặc timeout mới nhận được.
API Reference
Lấy thông báo chưa đọc
typescript
const response = await api.resource('messages').list({
filter: {
userId: currentUserId,
read: false,
},
sort: ['-createdAt'],
pageSize: 20,
});Đánh dấu đã đọc (một thông báo)
typescript
await api.resource('messages').update({
filterByTk: messageId,
values: { read: true },
});Đánh dấu tất cả đã đọc
typescript
await api.resource('messages').markAllRead();Đếm thông báo chưa đọc
typescript
const count = await api.resource('messages').count({
filter: {
userId: currentUserId,
read: false,
},
});Thành phần Client
MessageManagerProvider
Context provider quản lý toàn bộ state thông báo, sử dụng immer cho immutable updates:
- Danh sách thông báo
- Số lượng chưa đọc
- SSE connection state
- Actions: markAsRead, markAllRead, refresh
Desktop Components
| Component | Mô tả |
|---|---|
InboxPopup | Popup dropdown từ bell icon — danh sách thông báo |
NotificationBadge | Badge đếm số chưa đọc trên bell icon |
MessageItem | Render một thông báo trong danh sách |
Mobile Components
| Component | Mô tả |
|---|---|
InboxPage | Trang inbox toàn màn hình (antd-mobile) |
MobileMessageItem | Render thông báo tối ưu cho mobile |
MobileBadge | Badge trên tab bar |
Tuỳ chỉnh giao diện
Bạn có thể override các component thông qua hệ thống component của Digiforce:
typescript
app.addComponents({
'NotificationBadge': MyCustomBadge,
'InboxPopup': MyCustomInbox,
});Quan hệ với các plugin khác
- notification-manager: Bắt buộc — cung cấp registry, dispatch, logging
- mobile: Tuỳ chọn — plugin tự đăng ký mobile route nếu mobile plugin có mặt
- workflow: Tuỳ chọn — gửi thông báo từ workflow trigger