Appearance
私信接口
类说明
Message 类提供私信消息功能,包括发送消息、获取会话列表、查看聊天记录、拉黑管理等。
功能特点:
- 支持发送和接收私信
- 会话列表按最后消息时间排序
- 自动标记已读
- 首条消息限制(对方未回复前只能发一条)
- 频率限制(1分钟最多5条)
- 黑名单功能
- CSRF保护(状态变更接口)
安全机制:
- 不能给自己发消息
- 不能给拉黑的人发消息
- 被拉黑后无法发送消息
- 所有状态变更接口需要CSRF验证
发送私信
Method : POST
URL : /wp-json/vtheme/v1/messages/send
Auth required : True
Headers :
Authorization: BearerContent-Type: application/json
Body :
json
{
"receiver_id": 5,
"content": "你好,这是一条测试消息"
}参数说明:
receiver_id: [integer] 接收者用户IDcontent: [string] 消息内容
Success Response
Code : 200 OK
Content example :
json
{
"success": true,
"message": "发送成功",
"id": 123,
"sender_id": 1,
"receiver_id": 5,
"content": "你好,这是一条测试消息",
"created_at": "2023-01-01 12:00:00"
}Error Response
Code : 400 Bad Request
Content examples :
json
{
"error": "参数不完整"
}json
{
"error": "不能给自己发消息"
}Code : 401 Unauthorized
Content example :
json
{
"error": "401"
}Code : 403 Forbidden
Content examples :
json
{
"error": "您已被对方拉黑,无法发送消息"
}json
{
"error": "您已拉黑该用户,请先取消拉黑"
}json
{
"error": "对方尚未回复,您只能发送一条消息"
}Code : 404 Not Found
Content example :
json
{
"error": "用户不存在"
}Code : 429 Too Many Requests
Content example :
json
{
"error": "发送过于频繁,请稍后再试"
}Code : 500 Internal Server Error
Content example :
json
{
"error": "发送失败"
}获取会话列表
Method : GET
URL : /wp-json/vtheme/v1/messages/conversations
Auth required : True
Headers :
Authorization: Bearer
Query Parameters :
page: [integer] 页码,默认1per_page: [integer] 每页数量,默认20(范围1-100)
Success Response
Code : 200 OK
Content example :
json
[
{
"conversation_id": "1_5",
"unread_count": 3,
"other_user": {
"id": 5,
"display_name": "张三",
"avatar_url": "http://example.com/avatar.jpg"
},
"last_message": {
"id": 123,
"content": "最近怎么样?",
"sender_id": 5,
"created_at": "2023-01-01 12:00:00",
"is_read": 0
}
},
{
"conversation_id": "1_8",
"unread_count": 0,
"other_user": {
"id": 8,
"display_name": "李四",
"avatar_url": "http://example.com/avatar2.jpg"
},
"last_message": {
"id": 120,
"content": "好的,谢谢",
"sender_id": 1,
"created_at": "2023-01-01 11:00:00",
"is_read": 1
}
}
]返回字段说明:
conversation_id: 会话ID(格式:小ID_大ID)unread_count: 未读消息数other_user: 对话的另一方用户信息last_message: 最后一条消息
获取会话详情(聊天记录)
Method : GET
URL : /wp-json/vtheme/v1/messages/conversation/{user_id}
Auth required : True
URL Parameters :
user_id: [integer] 对话用户ID
Headers :
Authorization: Bearer
Query Parameters :
page: [integer] 页码,默认1per_page: [integer] 每页数量,默认50(范围1-100)
Success Response
Code : 200 OK
Content example :
json
{
"messages": [
{
"id": 1,
"sender_id": 1,
"receiver_id": 5,
"content": "你好",
"is_read": 1,
"created_at": "2023-01-01 10:00:00"
},
{
"id": 2,
"sender_id": 5,
"receiver_id": 1,
"content": "你好啊",
"is_read": 1,
"created_at": "2023-01-01 10:05:00"
}
],
"pagination": {
"current_page": 1,
"total_pages": 2,
"total_count": 75
}
}注意:
- 消息按时间升序排列(旧到新)
- 访问时会自动标记该会话中接收的消息为已读
获取未读消息总数
Method : GET
URL : /wp-json/vtheme/v1/messages/unread-count
Auth required : True
Headers :
Authorization: Bearer
Success Response
Code : 200 OK
Content example :
json
{
"unread_count": 5
}拉黑用户
Method : POST
URL : /wp-json/vtheme/v1/messages/block
Auth required : True
Headers :
Authorization: BearerX-WP-Nonce:Content-Type: application/json
Body :
json
{
"user_id": 5
}参数说明:
user_id: [integer] 要拉黑的用户ID
Success Response
Code : 200 OK
Content example :
json
{
"success": true,
"message": "已拉黑该用户"
}注意: 此接口具有幂等性,重复拉黑同一用户不会报错
Error Response
Code : 400 Bad Request
Content examples :
json
{
"error": "用户ID无效"
}json
{
"error": "不能拉黑自己"
}Code : 401 Unauthorized
Content example :
json
{
"error": "401"
}Code : 403 Forbidden (CSRF验证失败)
Content example :
json
{
"code": "invalid_nonce",
"message": "CSRF verification failed",
"data": {
"status": 403
}
}Code : 500 Internal Server Error
Content example :
json
{
"error": "操作失败"
}取消拉黑
Method : DELETE
URL : /wp-json/vtheme/v1/messages/block/{user_id}
Auth required : True
URL Parameters :
user_id: [integer] 要取消拉黑的用户ID
Headers :
Authorization: Bearer
Success Response
Code : 200 OK
Content example :
json
{
"success": true,
"message": "已取消拉黑"
}Error Response
Code : 400 Bad Request
Content example :
json
{
"error": "用户ID无效"
}Code : 401 Unauthorized
Content example :
json
{
"error": "401"
}Code : 500 Internal Server Error
Content example :
json
{
"error": "操作失败"
}获取黑名单列表
Method : GET
URL : /wp-json/vtheme/v1/messages/blocks
Auth required : True
Headers :
Authorization: Bearer
Query Parameters :
page: [integer] 页码,默认1per_page: [integer] 每页数量,默认20(范围1-100)
Success Response
Code : 200 OK
Content example :
json
[
{
"id": 1,
"created_at": "2023-01-01 12:00:00",
"blocked_user": {
"id": 5,
"display_name": "张三",
"avatar_url": "http://example.com/avatar.jpg"
}
},
{
"id": 2,
"created_at": "2023-01-02 12:00:00",
"blocked_user": {
"id": 8,
"display_name": "李四",
"avatar_url": "http://example.com/avatar2.jpg"
}
}
]使用示例
发送消息
javascript
// 发送消息
function sendMessage(receiverId, content) {
fetch('/wp-json/vtheme/v1/messages/send', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + ajax_object.wp_rest_nonce
},
body: JSON.stringify({
receiver_id: receiverId,
content: content
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('发送成功');
// 将消息添加到聊天界面
appendMessage(data);
// 清空输入框
document.getElementById('message-input').value = '';
}
})
.catch(error => {
console.error('发送失败:', error);
alert('发送失败,请稍后重试');
});
}
// 绑定发送按钮
document.getElementById('send-btn').addEventListener('click', () => {
const content = document.getElementById('message-input').value.trim();
const receiverId = document.getElementById('chat-container').dataset.userId;
if (content) {
sendMessage(receiverId, content);
}
});
// 支持回车发送
document.getElementById('message-input').addEventListener('keypress', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
document.getElementById('send-btn').click();
}
});获取会话列表
javascript
// 获取会话列表
function getConversations(page = 1) {
fetch(`/wp-json/vtheme/v1/messages/conversations?page=${page}&per_page=20`, {
headers: {
'Authorization': 'Bearer ' + ajax_object.wp_rest_nonce
}
})
.then(response => response.json())
.then(data => {
// 渲染会话列表
renderConversationList(data);
});
}
// 渲染会话列表
function renderConversationList(conversations) {
const container = document.getElementById('conversation-list');
container.innerHTML = conversations.map(conv => `
<div class="conversation-item" data-user-id="${conv.other_user.id}">
<img src="${conv.other_user.avatar_url}" alt="${conv.other_user.display_name}">
<div class="conversation-info">
<div class="conversation-name">${conv.other_user.display_name}</div>
<div class="last-message">${conv.last_message.content}</div>
</div>
${conv.unread_count > 0 ? `<span class="unread-badge">${conv.unread_count}</span>` : ''}
</div>
`).join('');
}获取聊天记录
javascript
// 获取聊天记录
function getConversation(userId, page = 1) {
fetch(`/wp-json/vtheme/v1/messages/conversation/${userId}?page=${page}&per_page=50`, {
headers: {
'Authorization': 'Bearer ' + ajax_object.wp_rest_nonce
}
})
.then(response => response.json())
.then(data => {
// 渲染消息列表
renderMessages(data.messages);
// 如果有更多,可以加载
if (data.pagination.current_page < data.pagination.total_pages) {
console.log('还有更多消息');
}
});
}
// 渲染消息
function renderMessages(messages) {
const container = document.getElementById('message-list');
const currentUserId = ajax_object.current_user_id;
container.innerHTML = messages.map(msg => `
<div class="message ${msg.sender_id == currentUserId ? 'sent' : 'received'}">
<div class="message-content">${msg.content}</div>
<div class="message-time">${formatTime(msg.created_at)}</div>
</div>
`).join('');
// 滚动到底部
container.scrollTop = container.scrollHeight;
}实时更新未读数
javascript
// 定时获取未读消息数
function updateUnreadCount() {
fetch('/wp-json/vtheme/v1/messages/unread-count', {
headers: {
'Authorization': 'Bearer ' + ajax_object.wp_rest_nonce
}
})
.then(response => response.json())
.then(data => {
const badge = document.getElementById('unread-badge');
if (data.unread_count > 0) {
badge.textContent = data.unread_count;
badge.style.display = 'block';
} else {
badge.style.display = 'none';
}
});
}
// 每30秒更新一次
setInterval(updateUnreadCount, 30000);拉黑/取消拉黑
javascript
// 拉黑用户
function blockUser(userId) {
if (!confirm('确定要拉黑该用户吗?拉黑后将无法收到对方的消息。')) {
return;
}
fetch('/wp-json/vtheme/v1/messages/block', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + ajax_object.wp_rest_nonce,
'X-WP-Nonce': ajax_object.wp_rest_nonce
},
body: JSON.stringify({
user_id: userId
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('已拉黑该用户');
// 刷新黑名单列表
loadBlocks();
}
});
}
// 取消拉黑
function unblockUser(userId) {
if (!confirm('确定要取消拉黑该用户吗?')) {
return;
}
fetch(`/wp-json/vtheme/v1/messages/block/${userId}`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer ' + ajax_object.wp_rest_nonce
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
alert('已取消拉黑');
// 从列表中移除
removeBlockItem(userId);
}
});
}
// 获取黑名单列表
function loadBlocks(page = 1) {
fetch(`/wp-json/vtheme/v1/messages/blocks?page=${page}&per_page=20`, {
headers: {
'Authorization': 'Bearer ' + ajax_object.wp_rest_nonce
}
})
.then(response => response.json())
.then(data => {
renderBlocksList(data);
});
}注意事项
首条消息限制:
- 如果对方从未回复过,你只能发送一条消息
- 这是为了防止骚扰
- 对方回复后可以正常聊天
频率限制:
- 1分钟内最多发送5条消息
- 超过限制会返回429错误
- 建议前端做防抖处理
黑名单机制:
- 拉黑后双方无法互相发送消息
- 拉黑操作具有幂等性
- 取消拉黑后可以恢复正常通信
已读标记:
- 查看聊天记录时会自动标记为已读
- 只标记接收的消息,不标记自己发送的
- 会话列表会显示未读数量
CSRF保护:
- 拉黑操作需要携带
X-WP-Nonce头 - Nonce 从
ajax_object.wp_rest_nonce获取 - 其他读取操作不需要Nonce
- 拉黑操作需要携带
会话ID规则:
- 会话ID格式:
小ID_大ID - 例如用户1和用户5的会话ID是
1_5 - 确保双方看到的是同一个会话
- 会话ID格式:
消息排序:
- 会话列表按最后消息时间降序
- 聊天记录按时间升序(旧到新)
- 新消息应该追加到末尾
性能优化:
- 聊天记录建议分页加载
- 可以实现无限滚动
- 考虑缓存最近的会话