2026-06-14 16:49:18 +08:00
|
|
|
|
// =============================================================================
|
|
|
|
|
|
// 企微IT智能服务台 — H5用户端消息 API
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
// 说明:封装消息相关的 API 调用
|
|
|
|
|
|
// 包括:消息撤回、删除、标记已读、图片上传、文件上传
|
|
|
|
|
|
// =============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
import apiClient from './index'
|
|
|
|
|
|
import type { AxiosResponse } from 'axios'
|
|
|
|
|
|
import type { Message } from './conversation'
|
|
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
// 类型定义
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/** 消息列表响应 */
|
|
|
|
|
|
export interface MessageListData {
|
|
|
|
|
|
items: Message[]
|
|
|
|
|
|
has_more: boolean
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
// API 函数
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 撤回消息(2分钟内)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param messageId - 消息ID
|
|
|
|
|
|
* @returns 撤回结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function recallMessage(messageId: string): Promise<any> {
|
|
|
|
|
|
const response: AxiosResponse = await apiClient.post(
|
|
|
|
|
|
`/messages/${messageId}/recall`
|
|
|
|
|
|
)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 删除消息
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param messageId - 消息ID
|
|
|
|
|
|
* @returns 删除结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function deleteMessage(messageId: string): Promise<any> {
|
|
|
|
|
|
const response: AxiosResponse = await apiClient.delete(
|
|
|
|
|
|
`/messages/${messageId}`
|
|
|
|
|
|
)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 标记会话已读
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param conversationId - 会话ID
|
|
|
|
|
|
* @returns 标记结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function markConversationRead(conversationId: string): Promise<any> {
|
|
|
|
|
|
const response: AxiosResponse = await apiClient.post(
|
|
|
|
|
|
`/conversations/${conversationId}/mark-read`
|
|
|
|
|
|
)
|
|
|
|
|
|
return response.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 轮询新消息(H5用户端)
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param afterMessageId - 上次轮询的最后一消息ID
|
|
|
|
|
|
* @returns 新消息列表
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function pollMessages(afterMessageId?: string): Promise<Message[]> {
|
|
|
|
|
|
const params: Record<string, string> = {}
|
|
|
|
|
|
if (afterMessageId) {
|
|
|
|
|
|
params.after_message_id = afterMessageId
|
|
|
|
|
|
}
|
|
|
|
|
|
const response: AxiosResponse = await apiClient.get(
|
|
|
|
|
|
'/h5/conversations/current/messages/poll',
|
|
|
|
|
|
{ params }
|
|
|
|
|
|
)
|
|
|
|
|
|
const data = response.data.data
|
|
|
|
|
|
const items = data?.items || []
|
|
|
|
|
|
// 映射后端字段到前端字段
|
|
|
|
|
|
return items.map((item: any) => ({
|
|
|
|
|
|
message_id: item.id || item.message_id || '',
|
|
|
|
|
|
conversation_id: item.conversation_id || '',
|
|
|
|
|
|
message_type: item.sender_type || 'text',
|
|
|
|
|
|
msg_type: item.msg_type,
|
|
|
|
|
|
content: item.content || '',
|
|
|
|
|
|
sender_name: item.sender_name || '',
|
|
|
|
|
|
created_at: item.created_at || '',
|
|
|
|
|
|
media_url: item.media_url,
|
|
|
|
|
|
file_name: item.file_name,
|
|
|
|
|
|
file_size: item.file_size,
|
|
|
|
|
|
extra_data: item.extra_data,
|
|
|
|
|
|
reply_to_id: item.reply_to_id,
|
|
|
|
|
|
status: item.status,
|
|
|
|
|
|
}))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 上传图片
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param file - 图片文件
|
|
|
|
|
|
* @returns 上传结果(包含 url, filename, file_size)
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function uploadImage(file: File): Promise<{
|
|
|
|
|
|
url: string
|
|
|
|
|
|
filename: string
|
|
|
|
|
|
file_size: number
|
|
|
|
|
|
}> {
|
|
|
|
|
|
const formData = new FormData()
|
|
|
|
|
|
formData.append('file', file)
|
|
|
|
|
|
|
|
|
|
|
|
const response: AxiosResponse = await apiClient.post(
|
|
|
|
|
|
'/messages/image',
|
|
|
|
|
|
formData,
|
|
|
|
|
|
{
|
2026-07-04 21:01:39 +08:00
|
|
|
|
// ISS-B4 修复:不显式设置 Content-Type,让浏览器自动生成带 boundary 的 multipart/form-data
|
2026-06-14 16:49:18 +08:00
|
|
|
|
headers: {
|
2026-07-04 21:01:39 +08:00
|
|
|
|
'Content-Type': undefined,
|
2026-06-14 16:49:18 +08:00
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
return response.data.data
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 上传文件
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param file - 文件
|
|
|
|
|
|
* @returns 上传结果(包含 url, filename, file_size)
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function uploadMessageFile(file: File): Promise<{
|
|
|
|
|
|
url: string
|
|
|
|
|
|
filename: string
|
|
|
|
|
|
file_size: number
|
|
|
|
|
|
}> {
|
|
|
|
|
|
const formData = new FormData()
|
|
|
|
|
|
formData.append('file', file)
|
|
|
|
|
|
|
|
|
|
|
|
const response: AxiosResponse = await apiClient.post(
|
|
|
|
|
|
'/messages/file',
|
|
|
|
|
|
formData,
|
|
|
|
|
|
{
|
2026-07-04 21:01:39 +08:00
|
|
|
|
// ISS-B4 修复:不显式设置 Content-Type,让浏览器自动生成带 boundary 的 multipart/form-data
|
2026-06-14 16:49:18 +08:00
|
|
|
|
headers: {
|
2026-07-04 21:01:39 +08:00
|
|
|
|
'Content-Type': undefined,
|
2026-06-14 16:49:18 +08:00
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
|
|
|
|
|
return response.data.data
|
|
|
|
|
|
}
|