Files
danyang-match/miniapp/services/messageService.js
T

112 lines
3.6 KiB
JavaScript
Raw Normal View History

2026-09-09 22:05:00 +08:00
/**
* 消息服务(API_INVENTORY 行 75-79, 84-87)
*
* 封装:会话列表 / 详情 / 历史消息 / 发送 / 未读数 + 通知列表 / 标记已读。
* 关键不变量(AGENTS.md):
* - 第 3 条:Mutual Match 后才能聊天——后端会返回 MATCH_REQUIRED,
* 前端在 send 失败时给出对应引导,不在 services 层做客户端校验。
* - 第 4 条:Block/Unmatch 后会话 canSendMessage=false,send 直接拒绝。
* - 第 7 条:工作人员不可看私人聊天——本层无任何 staff 入口。
* 消息发送走幂等键 messageId(规范 §106),防止弱网下重复入库。
*/
const api = require('../utils/api');
/**
* 获取会话列表(API_INVENTORY 行 75)
* @param {{ cursor?: string, pageSize?: number }} params
* @returns {Promise<{ items: Array<import('../types').Conversation>, nextCursor: string|null }>}
*/
function getConversations(params = {}) {
return api.get('/conversations', params);
}
/**
* 获取会话详情(API_INVENTORY 行 76)
* @param {string} conversationId
* @returns {Promise<import('../types').Conversation>}
*/
function getConversation(conversationId) {
return api.get(`/conversations/${encodeURIComponent(conversationId)}`);
}
/**
* 发送消息(API_INVENTORY 行 77)
* @param {string} conversationId
* @param {{ content: string, messageId: string, clientSentAt: number }} payload
* @returns {Promise<{ messageId: string, sentAt: number, status: 'sent' }>}
*/
function sendMessage(conversationId, payload) {
// 幂等键 = 客户端生成的 messageId(规范 §106),后端去重
return api.post(
`/conversations/${encodeURIComponent(conversationId)}/messages`,
payload,
undefined,
payload.messageId,
);
}
/**
* 获取消息历史(API_INVENTORY 行 78)
* @param {string} conversationId
* @param {{ before?: string, after?: string, pageSize?: number }} params
* @returns {Promise<{ items: Array<import('../types').Message>, nextCursor: string|null, hasMore: boolean }>}
*/
function getMessages(conversationId, params = {}) {
return api.get(`/conversations/${encodeURIComponent(conversationId)}/messages`, params);
}
/**
* 获取会话未读数(API_INVENTORY 行 79)
* @param {string} conversationId
* @returns {Promise<{ unreadCount: number }>}
*/
function getUnreadCount(conversationId) {
return api.get(`/conversations/${encodeURIComponent(conversationId)}/unread`);
}
/**
* 获取通知列表(API_INVENTORY 行 84)
* @param {{ cursor?: string, pageSize?: number, type?: string }} params
* @returns {Promise<{ items: Array<any>, nextCursor: string|null }>}
*/
function getNotifications(params = {}) {
return api.get('/notifications', params);
}
/**
* 标记单条通知已读(API_INVENTORY 行 85)
* @param {string} notificationId
* @returns {Promise<{ read: true }>}
*/
function markNotificationRead(notificationId) {
return api.put(`/notifications/${encodeURIComponent(notificationId)}/read`, {}, undefined, `notif-read:${notificationId}:${Date.now()}`);
}
/**
* 全部通知已读(API_INVENTORY 行 86)
* @returns {Promise<{ updated: number }>}
*/
function markAllNotificationsRead() {
return api.put('/notifications/read-all', {}, undefined, 'notif-read-all:' + Date.now());
}
/**
* 通知未读总数(API_INVENTORY 行 87)
* @returns {Promise<{ unreadCount: number }>}
*/
function getNotificationsUnreadCount() {
return api.get('/notifications/unread-count');
}
module.exports = {
getConversations,
getConversation,
sendMessage,
getMessages,
getUnreadCount,
getNotifications,
markNotificationRead,
markAllNotificationsRead,
getNotificationsUnreadCount,
};