从 main 同步站内信手动发送、媒体库选择、列表子路由重构等 API/Admin 改动;玩家端仅合并 ADMIN_CUSTOM 富文本、消息预览与充值截图压缩逻辑,保留 theme-3 样式。
132 lines
3.2 KiB
TypeScript
132 lines
3.2 KiB
TypeScript
import { ref } from 'vue';
|
|
import api from '../api';
|
|
|
|
export type PlayerMessageType =
|
|
| 'DEPOSIT_APPROVED'
|
|
| 'DEPOSIT_REJECTED'
|
|
| 'BANNER_PROMO'
|
|
| 'ANNOUNCEMENT_PROMO'
|
|
| 'ADMIN_CUSTOM';
|
|
|
|
export type DepositMessagePayload = {
|
|
depositOrderId?: string;
|
|
orderNo?: string;
|
|
amount?: string;
|
|
approvedAmount?: string | null;
|
|
rejectReason?: string | null;
|
|
};
|
|
|
|
export type BannerPromoPayload = {
|
|
contentId?: string;
|
|
};
|
|
|
|
export interface PlayerMessage {
|
|
id: string;
|
|
type: PlayerMessageType | string;
|
|
title: string;
|
|
body: string;
|
|
payload: DepositMessagePayload | BannerPromoPayload | null;
|
|
readAt: string | null;
|
|
createdAt: string;
|
|
isRead: boolean;
|
|
}
|
|
|
|
interface MessageListResponse {
|
|
items: PlayerMessage[];
|
|
total: number;
|
|
unreadCount: number;
|
|
page: number;
|
|
pageSize: number;
|
|
}
|
|
|
|
const unreadCount = ref(0);
|
|
const messages = ref<PlayerMessage[]>([]);
|
|
const loading = ref(false);
|
|
const listLoaded = ref(false);
|
|
|
|
async function refreshUnreadCount() {
|
|
try {
|
|
const { data } = await api.get('/player/messages/unread-count');
|
|
unreadCount.value = Number(data.data?.unreadCount ?? 0);
|
|
} catch {
|
|
/* silent */
|
|
}
|
|
}
|
|
|
|
async function loadMessages(page = 1, append = false) {
|
|
loading.value = true;
|
|
try {
|
|
const { data } = await api.get('/player/messages', { params: { page, pageSize: 20 } });
|
|
const payload = data.data as MessageListResponse;
|
|
const items = payload?.items ?? [];
|
|
messages.value = append ? [...messages.value, ...items] : items;
|
|
unreadCount.value = Number(payload?.unreadCount ?? unreadCount.value);
|
|
listLoaded.value = true;
|
|
return payload;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
}
|
|
|
|
async function loadMessageDetail(id: string) {
|
|
const { data } = await api.get(`/player/messages/${id}`);
|
|
return data.data as PlayerMessage;
|
|
}
|
|
|
|
async function markMessageRead(id: string) {
|
|
const { data } = await api.patch(`/player/messages/${id}/read`);
|
|
const updated = data.data as PlayerMessage;
|
|
messages.value = messages.value.map((item) =>
|
|
item.id === id ? { ...item, ...updated, isRead: true } : item,
|
|
);
|
|
if (unreadCount.value > 0) unreadCount.value -= 1;
|
|
return updated;
|
|
}
|
|
|
|
async function markAllRead() {
|
|
await api.patch('/player/messages/read-all');
|
|
messages.value = messages.value.map((item) => ({
|
|
...item,
|
|
isRead: true,
|
|
readAt: item.readAt ?? new Date().toISOString(),
|
|
}));
|
|
unreadCount.value = 0;
|
|
}
|
|
|
|
async function deleteMessage(id: string) {
|
|
const { data } = await api.delete(`/player/messages/${id}`);
|
|
const wasUnread = Boolean(data.data?.wasUnread);
|
|
messages.value = messages.value.filter((item) => item.id !== id);
|
|
if (wasUnread && unreadCount.value > 0) unreadCount.value -= 1;
|
|
}
|
|
|
|
async function deleteAllMessages() {
|
|
await api.delete('/player/messages');
|
|
messages.value = [];
|
|
unreadCount.value = 0;
|
|
listLoaded.value = true;
|
|
}
|
|
|
|
function resetMessagesState() {
|
|
unreadCount.value = 0;
|
|
messages.value = [];
|
|
listLoaded.value = false;
|
|
}
|
|
|
|
export function usePlayerMessages() {
|
|
return {
|
|
unreadCount,
|
|
messages,
|
|
loading,
|
|
listLoaded,
|
|
refreshUnreadCount,
|
|
loadMessages,
|
|
loadMessageDetail,
|
|
markMessageRead,
|
|
markAllRead,
|
|
deleteMessage,
|
|
deleteAllMessages,
|
|
resetMessagesState,
|
|
};
|
|
}
|