XuqmGroup-RNSDK/packages/im/src/upload.ts
XuqmGroup 2ca58aa458 feat(sample): 添加示例应用的核心功能模块
- 实现环境配置管理,支持外部和本地主机模式切换
- 集成Demo API接口,包含登录、注册、文件上传等功能
- 构建附件处理仓库,支持图片、视频、音频和文件发送
- 开发认证仓库,管理用户会话和IM令牌刷新机制
- 添加语音录制功能,支持实时音频消息录制
- 创建依赖注入容器,统一管理应用组件实例
- 实现登录界面,提供用户认证交互功能
- 开发聊天界面,集成消息收发和媒体处理功能
2026-04-28 16:08:07 +08:00

97 行
2.4 KiB
TypeScript

import { getConfig, _getToken } from '@xuqm/rn-common'
export interface UploadResult {
url: string
thumbnailUrl: string | null
hash: string
size: number
originalName: string
mimeType: string
ext?: string
}
/**
* Upload a file to the file-service using multipart/form-data.
* Optionally attach a pre-generated thumbnail (for video files).
* Requires an active IM session (Bearer token) for authentication.
*/
export async function uploadFile(
localUri: string,
mimeType: string,
filename: string,
thumbnailUri?: string,
): Promise<UploadResult> {
const config = getConfig()
const token = await _getToken()
if (!token) {
throw new Error('[uploadFile] No active session — call ImSDK.login() first.')
}
const form = new FormData()
// React Native FormData accepts an object with uri/name/type for file parts
form.append('file', {
uri: localUri,
name: filename,
type: mimeType,
} as unknown as Blob)
if (thumbnailUri) {
form.append('thumbnail', {
uri: thumbnailUri,
name: 'thumbnail.jpg',
type: 'image/jpeg',
} as unknown as Blob)
}
if (config.debug) {
console.debug('[XuqmSDK][Upload] request', {
url: `${config.fileServiceUrl}/api/file/upload`,
filename,
mimeType,
hasThumbnail: Boolean(thumbnailUri),
})
}
const response = await fetch(`${config.fileServiceUrl}/api/file/upload`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
// Do NOT set Content-Type — let fetch set it with the correct boundary
},
body: form,
})
if (!response.ok) {
const text = await response.text().catch(() => '')
if (config.debug) {
console.debug('[XuqmSDK][Upload] response', {
status: response.status,
ok: false,
body: text,
})
}
throw new Error(`[uploadFile] Upload failed (${response.status}): ${text}`)
}
const json = await response.json()
if (config.debug) {
console.debug('[XuqmSDK][Upload] response', {
status: response.status,
ok: true,
})
}
// Server wraps result in ApiResponse { code, data, message }
const data = json?.data ?? json
return {
url: data.url,
thumbnailUrl: data.thumbnailUrl ?? null,
hash: data.hash,
size: data.size,
originalName: data.originalName,
mimeType: data.mimeType,
ext: data.ext,
}
}