feat(admin+api+player): 站内信手动发送、媒体库选择与发送记录详情
新增管理员手动发送站内信(三语富文本),支持发送记录查看与删除;修复全站「从媒体库选择」因分类过滤导致列表为空的问题;玩家端支持渲染管理员自定义消息;并优化后台列表页双层卡片布局。
This commit is contained in:
@@ -820,6 +820,28 @@ export const adminPagesMs: Record<string, string> = {
|
||||
'content.inbox_notify.manual_title': 'Tanda "Notifikasi peti mesej" semasa mencipta:',
|
||||
'content.inbox_notify.banner_note': 'Promosi laman utama',
|
||||
'content.inbox_notify.announcement_note': 'Notifikasi / ticker',
|
||||
'content.inbox_broadcast.title': 'Hantar manual',
|
||||
'content.inbox_broadcast.hint': 'Hantar mesej peti secara manual kepada pemain. Padam rekod juga membuang mesej di peti pemain.',
|
||||
'content.inbox_broadcast.field_title': 'Tajuk',
|
||||
'content.inbox_broadcast.field_body': 'Kandungan',
|
||||
'content.inbox_broadcast.field_target': 'Penerima',
|
||||
'content.inbox_broadcast.field_username': 'Nama pengguna pemain',
|
||||
'content.inbox_broadcast.target_all': 'Semua pemain',
|
||||
'content.inbox_broadcast.target_user': 'Pemain tertentu',
|
||||
'content.inbox_broadcast.username_placeholder': 'Masukkan nama log masuk pemain',
|
||||
'content.inbox_broadcast.send': 'Hantar',
|
||||
'content.inbox_broadcast.send_success': 'Dihantar kepada {n} pemain',
|
||||
'content.inbox_broadcast.form_invalid': 'Sila isi tajuk atau kandungan sekurang-kurangnya satu bahasa',
|
||||
'content.inbox_broadcast.target_user_required': 'Nama pengguna pemain diperlukan',
|
||||
'content.inbox_broadcast.history_title': 'Sejarah penghantaran',
|
||||
'content.inbox_broadcast.view_title': 'Butiran penghantaran',
|
||||
'content.inbox_broadcast.col_title': 'Tajuk',
|
||||
'content.inbox_broadcast.col_target': 'Sasaran',
|
||||
'content.inbox_broadcast.col_recipients': 'Bilangan',
|
||||
'content.inbox_broadcast.col_sender': 'Penghantar',
|
||||
'content.inbox_broadcast.col_time': 'Masa',
|
||||
'content.inbox_broadcast.delete_confirm': 'Padam "{title}"? Salinan di peti pemain juga akan dibuang.',
|
||||
'content.inbox_broadcast.locale_fallback_hint': 'Locale yang kosong akan guna susunan: bahasa pemain → Inggeris → Cina Ringkas → Melayu.',
|
||||
'content.hint.banner': 'Dipaparkan dalam karusel laman utama; ketik untuk halaman butiran. Muat naik imej muka depan dan kandungan kaya seperti pengumuman laman rasmi.',
|
||||
'content.hint.announcement': 'Dipaparkan sebagai teks bergulir di bahagian atas aplikasi pemain. Isi tajuk dan teks bergulir setiap bahasa — teks biasa sahaja.',
|
||||
'content.section.publish': 'Tetapan terbitan',
|
||||
@@ -837,6 +859,7 @@ export const adminPagesMs: Record<string, string> = {
|
||||
'content.upload.cover_size_hint': 'Lebar disyorkan 860px+. Imej muka depan dan dalam kandungan akan menyesuaikan lebar pada pemain.',
|
||||
'content.upload.pick_media_title': 'Pilih imej',
|
||||
'content.upload.no_media': 'Tiada imej dalam pustaka — muat naik dahulu',
|
||||
'content.upload.load_media_failed': 'Gagal memuat pustaka media',
|
||||
'content.status.DRAFT': 'Draf',
|
||||
'content.status.ACTIVE': 'Aktif',
|
||||
'content.status.INACTIVE': 'Tidak aktif',
|
||||
|
||||
@@ -888,6 +888,7 @@ export const adminPagesZh: Record<string, string> = {
|
||||
'content.upload.pick_media': '从媒体库选择',
|
||||
'content.upload.pick_media_title': '选择图片',
|
||||
'content.upload.no_media': '媒体库中暂无图片,请先上传',
|
||||
'content.upload.load_media_failed': '加载媒体库失败',
|
||||
'content.upload.url_placeholder': '或手动粘贴图片 URL',
|
||||
'content.upload.recommended_size': '建议尺寸:860 x 360 px,或 43:18 同比例图片;前台会完整显示并自动填充不合比例区域。',
|
||||
'content.link.none': '无跳转',
|
||||
@@ -1987,6 +1988,7 @@ export const adminPagesEn: Record<string, string> = {
|
||||
'content.upload.pick_media': 'Pick from library',
|
||||
'content.upload.pick_media_title': 'Select image',
|
||||
'content.upload.no_media': 'No images in library — upload one first',
|
||||
'content.upload.load_media_failed': 'Failed to load media library',
|
||||
'content.upload.url_placeholder': 'Or paste image URL',
|
||||
'content.upload.recommended_size': 'Recommended size: 860 x 360 px, or any 43:18 image. The player carousel keeps the full image visible and fills extra space.',
|
||||
'content.link.none': 'No link',
|
||||
|
||||
@@ -829,6 +829,7 @@ const adminPages: Record<string, string> = {
|
||||
|
||||
'content.upload.pick_media_title': 'Select image',
|
||||
'content.upload.no_media': 'No images in library — upload one first',
|
||||
'content.upload.load_media_failed': 'Failed to load media library',
|
||||
'content.btn.create': 'New content',
|
||||
'content.btn.enable': 'Enable',
|
||||
'content.btn.disable': 'Disable',
|
||||
@@ -849,6 +850,28 @@ const adminPages: Record<string, string> = {
|
||||
'content.inbox_notify.manual_title': 'Check "Inbox notify" when creating:',
|
||||
'content.inbox_notify.banner_note': 'Homepage promo',
|
||||
'content.inbox_notify.announcement_note': 'Announcements / ticker',
|
||||
'content.inbox_broadcast.title': 'Manual send',
|
||||
'content.inbox_broadcast.hint': 'Manually send inbox messages to players. Deleting a record also removes the message from player inboxes.',
|
||||
'content.inbox_broadcast.field_title': 'Title',
|
||||
'content.inbox_broadcast.field_body': 'Body',
|
||||
'content.inbox_broadcast.field_target': 'Recipients',
|
||||
'content.inbox_broadcast.field_username': 'Player username',
|
||||
'content.inbox_broadcast.target_all': 'All players',
|
||||
'content.inbox_broadcast.target_user': 'Single player',
|
||||
'content.inbox_broadcast.username_placeholder': 'Enter player login username',
|
||||
'content.inbox_broadcast.send': 'Send',
|
||||
'content.inbox_broadcast.send_success': 'Sent to {n} player(s)',
|
||||
'content.inbox_broadcast.form_invalid': 'Provide a title or body in at least one language',
|
||||
'content.inbox_broadcast.target_user_required': 'Player username is required',
|
||||
'content.inbox_broadcast.history_title': 'Send history',
|
||||
'content.inbox_broadcast.view_title': 'Send details',
|
||||
'content.inbox_broadcast.col_title': 'Title',
|
||||
'content.inbox_broadcast.col_target': 'Target',
|
||||
'content.inbox_broadcast.col_recipients': 'Count',
|
||||
'content.inbox_broadcast.col_sender': 'Sender',
|
||||
'content.inbox_broadcast.col_time': 'Sent at',
|
||||
'content.inbox_broadcast.delete_confirm': 'Delete "{title}"? Player inbox copies will be removed too.',
|
||||
'content.inbox_broadcast.locale_fallback_hint': 'Missing locales fall back in order: player language → English → Simplified Chinese → Malay.',
|
||||
'content.hint.banner': 'Shown in the home carousel; tapping opens the detail page. Add a cover image and rich body like an official site announcement.',
|
||||
'content.hint.announcement': 'Shows as a scrolling marquee at the top of the player app. Enter title and marquee text per language — plain text only.',
|
||||
'content.section.publish': 'Publish settings',
|
||||
|
||||
@@ -847,6 +847,28 @@ const adminPages: Record<string, string> = {
|
||||
'content.inbox_notify.manual_title': '以下类型在新建时勾选「邮箱通知」',
|
||||
'content.inbox_notify.banner_note': '首页推广',
|
||||
'content.inbox_notify.announcement_note': '通知公告 / 跑马灯',
|
||||
'content.inbox_broadcast.title': '手动发送',
|
||||
'content.inbox_broadcast.hint': '手动向玩家发送站内信;删除记录将同时撤回玩家端对应消息。',
|
||||
'content.inbox_broadcast.field_title': '标题',
|
||||
'content.inbox_broadcast.field_body': '正文',
|
||||
'content.inbox_broadcast.field_target': '发送对象',
|
||||
'content.inbox_broadcast.field_username': '玩家账号',
|
||||
'content.inbox_broadcast.target_all': '全部玩家',
|
||||
'content.inbox_broadcast.target_user': '指定玩家',
|
||||
'content.inbox_broadcast.username_placeholder': '输入玩家登录账号',
|
||||
'content.inbox_broadcast.send': '发送',
|
||||
'content.inbox_broadcast.send_success': '已发送给 {n} 位玩家',
|
||||
'content.inbox_broadcast.form_invalid': '请至少填写一种语言的标题或正文',
|
||||
'content.inbox_broadcast.target_user_required': '请填写玩家账号',
|
||||
'content.inbox_broadcast.history_title': '发送记录',
|
||||
'content.inbox_broadcast.view_title': '发送详情',
|
||||
'content.inbox_broadcast.col_title': '标题',
|
||||
'content.inbox_broadcast.col_target': '对象',
|
||||
'content.inbox_broadcast.col_recipients': '人数',
|
||||
'content.inbox_broadcast.col_sender': '发送人',
|
||||
'content.inbox_broadcast.col_time': '发送时间',
|
||||
'content.inbox_broadcast.delete_confirm': '确定删除「{title}」?玩家端对应消息将一并删除。',
|
||||
'content.inbox_broadcast.locale_fallback_hint': '未填写的语言将按玩家语言 → 英文 → 简体中文 → 马来语顺序回退使用已有内容。',
|
||||
'content.hint.banner': '用于首页轮播展示,点击后进入通知详情页;请填写封面图与正文,像官网发布活动通知一样编辑。',
|
||||
'content.hint.announcement': '在玩家端顶部显示滚动跑马灯文字;填写各语言标题与滚动文案即可,纯文本无富文本。',
|
||||
'content.section.publish': '发布设置',
|
||||
@@ -864,6 +886,7 @@ const adminPages: Record<string, string> = {
|
||||
'content.upload.cover_size_hint': '建议宽度 860px 以上;玩家端详情页会完整显示封面,正文内图片也会自适应宽度。',
|
||||
'content.upload.pick_media_title': '选择图片',
|
||||
'content.upload.no_media': '媒体库中暂无图片,请先上传',
|
||||
'content.upload.load_media_failed': '加载媒体库失败',
|
||||
'content.status.DRAFT': '草稿',
|
||||
'content.status.ACTIVE': '已启用',
|
||||
'content.status.INACTIVE': '已停用',
|
||||
|
||||
Reference in New Issue
Block a user