Quản lý Tin tức & Popup#
Mục tiêu: Admin tạo và quản lý News — entity hiển thị popup/banner/notice/list cho Influencer trên Creator Portal.
Mục tiêu#
- Hiểu 4 type của News và vị trí hiển thị.
- Tạo/edit/clone news.
- Cấu hình schedule, target partner, priority (
order). - Hiểu logic hiển thị trên Creator Portal (đặc biệt khi nhiều popup cùng lúc).
Điều kiện tiên quyết#
- Quyền CMS / News.
- Đã chuẩn bị nội dung: title, ảnh, CTA action, khoảng thời gian chạy.
4 loại News (type)#
| Type | Tên tiếng Việt | Vị trí hiển thị |
|---|---|---|
| popup | Popup | Modal toàn màn hình, hiển thị khi Influencer vào home |
| home_banner | Banner trang chủ | Banner slider ở đầu trang home |
| home_notice | Thông báo trang chủ | Strip thông báo cố định trên cùng home |
| home_list | Danh sách trang chủ | Card trong khu vực tin tức trang home |
Các bước thực hiện#
1. Xem danh sách#
- Vào
/news. - Bảng hiển thị các cột:
| Cột | Ý nghĩa |
|---|---|
| Ảnh bìa | |
| Tiêu đề | |
| Mã code | Unique identifier |
| Partner | Target partner (TCB / AT / ...) |
| Loại tin | popup / banner / notice / list |
Thời gian bắt đầu (startAt) | |
Thời gian kết thúc (endAt) | |
Thứ tự (order) | Priority number |
| Trạng thái | active / inactive |
| Actions | Edit, Clone, Toggle status |
2. Tạo news mới#
- Bấm Tạo mới.
- Điền form:
- Tiêu đề (bắt buộc)
- Mã code (bắt buộc, unique) — ví dụ:
popup_q2_2026_campaign_launch - Mô tả ngắn (bắt buộc)
- Thứ tự (bắt buộc, mặc định 0) — số càng nhỏ càng ưu tiên cao
- Loại tin (bắt buộc) — chọn 1 trong 4 type
- Thời gian (bắt buộc) — date range
startAt→endAt(formatYYYY-MM-DD HH:mm:ss) - Partner (bắt buộc nếu type = popup hoặc home_banner) — target partner
- Hành động (Action) (tùy chọn):
URL— mở link externalINTERNAL_LINK— điều hướng trong appARTICLE— mở bài viết CMSNONE— chỉ đọc
- Ảnh bìa — ảnh chính
- Ảnh stretched — phiên bản stretched (cho layout khác)
- Nội dung — rich text (Braft HTML) hoặc Markdown (chọn radio)
- Lưu → status mặc định active.
3. Edit / Toggle / Clone#
- Edit — mở form, sửa field.
- Toggle status — active ↔ inactive (không xóa, chỉ ẩn).
- Clone — copy news hiện có làm template cho news mới.
4. Preview#
Không có preview built-in trong admin. Để verify:
- Tạo news active với schedule bao gồm thời điểm hiện tại.
- Mở Creator Portal bằng tài khoản test thuộc đúng partner.
- Kiểm tra popup hiện đúng.
Logic hiển thị cho Influencer (quan trọng)#
Khi nào popup được fetch#
- Frontend gọi
GET /news?type=popupkhi app khởi tạo hoặc khi vào trang home. - Backend trả về array các news match điều kiện.
Điều kiện hiển thị#
Backend filter theo:
- Schedule active:
startAt ≤ now ≤ endAt. - Status = active.
- Partner match:
news.partner= partner của user đang login (nếu user chưa login → chỉ show news không gắn partner cụ thể, hoặc public news).
⚠️ Không có filter theo segment, role CBNV, demographics ở phiên bản hiện tại. Muốn target segment → phải dùng feature Notification thay vì popup.
Thứ tự hiển thị khi nhiều popup#
Đây là điểm quan trọng:
-
Sort theo
order(field trong entity):- Số nhỏ hơn = ưu tiên cao hơn.
- Ví dụ: order=1 hiển thị trước order=5.
-
Cùng
orderthì sao?- Backend dùng tie-breaker (thường
createdAt desc— mới tạo trước). - Tuy nhiên, không deterministic 100% từ góc độ admin.
- Best practice: luôn đặt
orderkhác nhau cho các popup cùng thời gian active để tránh ambiguous.
- Backend dùng tie-breaker (thường
-
Frontend chỉ hiển thị popup đầu tiên trong array (
news[0]) ở 1 thời điểm:- Không stack 2 popup chồng lên nhau.
- Không queue (show popup A, đóng xong show popup B).
- Nghĩa là popup ưu tiên cao nhất "thắng", các popup khác không thấy.
-
Hệ quả thực tế:
- Nếu cần cả 2 popup cùng chạy → chia schedule không overlap.
- Nếu popup A ưu tiên cao, popup B cũng muốn user thấy → dùng
home_bannerhoặchome_listcho B thay vì popup.
"Đã xem" / Dismiss#
- Popup KHÔNG nhớ đã xem. Reload trang là hiện lại (user sẽ bực nếu tần suất cao).
- Khác với home_notice — type này lưu
hideHomeNotice = news._idvào localStorage → user dismiss 1 lần là không thấy nữa. - Best practice cho popup: schedule ngắn (1–3 ngày), message tối giản, có CTA rõ ràng.
Chi tiết từng phần#
Field order — cách sử dụng#
| Use case | Order |
|---|---|
| Popup promo lớn (big announcement) | 0 hoặc 1 |
| Popup event secondary | 10, 20 |
| Popup nhẹ nhàng / optional | 50+ |
Để sẵn "khe" giữa các giá trị (10, 20, 30...) để sau này chèn được mà không phải renumber tất cả.
Partner scope#
- Chỉ type popup và home_banner có partner filter (bắt buộc).
- home_notice và home_list không cần partner — hiển thị all users.
Schedule best practices#
- Timezone: giờ Việt Nam (UTC+7). Đảm bảo
startAtkhông vượt quá giờ hiện tại khi tạo (vừa set vừa save → tránh popup hiện trước khi kịp review). - Overlap: nếu 2 popup cùng khoảng thời gian, chỉ 1 (order thấp nhất) hiện. Nên schedule không overlap.
CTA (action)#
Action khi user click popup:
URL— external (ví dụ: link landing page Techcombank).INTERNAL_LINK— deep link trong app (ví dụ:/tai-khoan,/thu-thach/abc).ARTICLE— mở bài CMS Article cụ thể.NONE— popup là info-only, không click.
Thống kê#
Mỗi news có statistic:
view— tổng views.uniqueView— unique users đã xem.
Dùng để đo hiệu quả popup.
Lỗi thường gặp#
1. Tạo popup xong user không thấy#
Checklist:
status = active?startAt ≤ now ≤ endAt?- User thuộc
partnerđã set? - Có popup khác
orderthấp hơn đang chạy? (popup đó "nuốt" popup của bạn)
2. Popup quá "nặng" / phiền user#
- Reload vẫn show → user bực.
- Fix: shorten schedule, hoặc dùng home_notice (có dismiss memory) thay popup.
3. 2 popup launched cùng ngày → chỉ 1 hiện#
- Cùng
order→ ambiguous. Đặt order khác nhau. - Chọn priority, push popup kia sang khung giờ khác.
4. Partner filter không khớp#
- User là CBNV TCB nhưng popup set partner = AT → không thấy.
- Check kỹ user thuộc partner nào trước khi set.
5. CTA không hoạt động#
- URL sai.
- Internal link sai path.
- Article code không tồn tại trong CMS.
Test click trước khi publish.
6. Rich text xuống dòng không đúng#
- Braft HTML có thể render khác nhau giữa admin preview và creator portal. Test trước.
Câu hỏi thường gặp (FAQ)#
Tôi muốn target theo segment (ví dụ: chỉ VIP Influencer) — làm sao?
Hiện tại news không support segment filter. Giải pháp:
- Dùng Notification thay vì popup (targetUsers=USER_SEGMENT).
- Hoặc request Product/Dev mở rộng entity news có thêm field
segments.
Popup hiển thị khi user chưa login?
Có, nếu partner setting cho phép public. Thường popup đăng ký/giới thiệu nền tảng sẽ public.
Popup có thể target theo giới tính/tuổi không?
Không. Hệ thống hiện tại không filter demographics.
Sao số view trong statistic không khớp với số user?
view tăng mỗi lần render (reload app). uniqueView đếm unique user — con số này mới dùng làm KPI chính.
Mã code có tác dụng gì ngoài unique?
- Tra cứu trong audit log.
- Deep-link từ bên ngoài (ví dụ:
/news?code=xxx). - Analytics tracking.
Clone news xong có tự active?
Clone tạo bản sao status = inactive. Admin kiểm tra và toggle active khi sẵn sàng.
Nhiều popup trong ngày lớn (Black Friday, sự kiện Tet) — xử lý sao?
- Chia theo khung giờ (9h–12h: popup A, 12h–18h: popup B).
- Hoặc gộp nhiều content vào 1 popup (carousel).
- Hoặc dùng các type khác (banner, list) cho secondary content.
Popup test trên staging sau đó publish production?
Tạo news trên staging với code khác. Verify. Khi OK, tạo trên production với cùng content + code mới. Không có sync tự động giữa 2 env.
Liên kết liên quan#
- Quản lý bài viết (CMS) — Article khác News
- Gửi thông báo — Nếu cần target segment
- Segment
Tham khảo SRS: admin-portal/10-cms-notification