// ============================================================================= // 企微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 { const response: AxiosResponse = await apiClient.post( `/messages/${messageId}/recall` ) return response } /** * 删除消息 * * @param messageId - 消息ID * @returns 删除结果 */ export async function deleteMessage(messageId: string): Promise { const response: AxiosResponse = await apiClient.delete( `/messages/${messageId}` ) return response } /** * 标记会话已读 * * @param conversationId - 会话ID * @returns 标记结果 */ export async function markConversationRead(conversationId: string): Promise { const response: AxiosResponse = await apiClient.post( `/conversations/${conversationId}/mark-read` ) return response } /** * 轮询新消息(H5用户端) * * @param afterMessageId - 上次轮询的最后一消息ID * @returns 新消息列表 */ export async function pollMessages(afterMessageId?: string): Promise { const params: Record = {} if (afterMessageId) { params.after_message_id = afterMessageId } const response: AxiosResponse = await apiClient.get( '/h5/conversations/current/messages/poll', { params } ) const data = response 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, { // ISS-B4 修复:不显式设置 Content-Type,让浏览器自动生成带 boundary 的 multipart/form-data headers: { 'Content-Type': undefined, }, } ) return response } /** * 上传文件 * * @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, { // ISS-B4 修复:不显式设置 Content-Type,让浏览器自动生成带 boundary 的 multipart/form-data headers: { 'Content-Type': undefined, }, } ) return response }