feat(sample): 添加示例应用的核心功能模块

- 实现环境配置管理,支持外部和本地主机模式切换
- 集成Demo API接口,包含登录、注册、文件上传等功能
- 构建附件处理仓库,支持图片、视频、音频和文件发送
- 开发认证仓库,管理用户会话和IM令牌刷新机制
- 添加语音录制功能,支持实时音频消息录制
- 创建依赖注入容器,统一管理应用组件实例
- 实现登录界面,提供用户认证交互功能
- 开发聊天界面,集成消息收发和媒体处理功能
这个提交包含在:
XuqmGroup 2026-04-28 16:08:07 +08:00
父节点 2d1bebeeb5
当前提交 2ca58aa458
共有 10 个文件被更改,包括 55 次插入6 次删除

查看文件

@ -6,7 +6,7 @@
"main": "src/index.ts", "main": "src/index.ts",
"react-native": "src/index.ts", "react-native": "src/index.ts",
"types": "src/index.ts", "types": "src/index.ts",
"private": false, "private": true,
"workspaces": ["packages/*"], "workspaces": ["packages/*"],
"publishConfig": { "publishConfig": {
"registry": "https://nexus.xuqinmin.com/repository/npm-hosted/" "registry": "https://nexus.xuqinmin.com/repository/npm-hosted/"

查看文件

@ -2,6 +2,7 @@
"name": "@xuqm/rn-common", "name": "@xuqm/rn-common",
"version": "0.2.0", "version": "0.2.0",
"description": "XuqmGroup RN SDK — core: init, network, token management", "description": "XuqmGroup RN SDK — core: init, network, token management",
"license": "UNLICENSED",
"main": "src/index.ts", "main": "src/index.ts",
"react-native": "src/index.ts", "react-native": "src/index.ts",
"types": "src/index.ts", "types": "src/index.ts",

查看文件

@ -1,6 +1,6 @@
export interface XuqmInitOptions { export interface XuqmInitOptions {
appId: string appId: string
serverUrl: string // e.g. "https://dev.xuqinmin.com" — SDK fetches config from here serverUrl: string // e.g. "http://192.168.116.9:8081" — SDK fetches config from here
appKey?: string appKey?: string
debug?: boolean debug?: boolean
} }

查看文件

@ -4,9 +4,9 @@
* XuqmSDK.initialize(). These constants are kept only as fallback * XuqmSDK.initialize(). These constants are kept only as fallback
* references and for backward compatibility. * references and for backward compatibility.
*/ */
export const API_BASE_URL = 'https://dev.xuqinmin.com' export const API_BASE_URL = 'http://192.168.116.9:8081'
/** /**
* @deprecated See API_BASE_URL. * @deprecated See API_BASE_URL.
*/ */
export const IM_WS_URL = 'wss://dev.xuqinmin.com/ws/im' export const IM_WS_URL = 'ws://192.168.116.9:8082/ws/im'

查看文件

@ -42,6 +42,14 @@ export async function apiRequest<T>(
if (token) headers['Authorization'] = `Bearer ${token}` if (token) headers['Authorization'] = `Bearer ${token}`
} }
if (config.debug) {
console.debug('[XuqmSDK][HTTP] request', {
method: options.method ?? 'GET',
url,
hasBody: Boolean(options.body),
})
}
const res = await fetch(url, { const res = await fetch(url, {
method: options.method ?? 'GET', method: options.method ?? 'GET',
headers, headers,
@ -50,9 +58,24 @@ export async function apiRequest<T>(
if (!res.ok) { if (!res.ok) {
const err = await res.json().catch(() => ({ message: res.statusText })) const err = await res.json().catch(() => ({ message: res.statusText }))
if (config.debug) {
console.debug('[XuqmSDK][HTTP] response', {
url,
status: res.status,
ok: false,
message: (err as { message?: string }).message ?? res.statusText,
})
}
throw new Error((err as { message?: string }).message ?? `HTTP ${res.status}`) throw new Error((err as { message?: string }).message ?? `HTTP ${res.status}`)
} }
const json = await res.json() const json = await res.json()
if (config.debug) {
console.debug('[XuqmSDK][HTTP] response', {
url,
status: res.status,
ok: true,
})
}
return (json.data ?? json) as T return (json.data ?? json) as T
} }

查看文件

@ -6,7 +6,7 @@ export const XuqmSDK = {
* Recommended for production use. * Recommended for production use.
* *
* @param options.appId - Your application ID (from the tenant platform) * @param options.appId - Your application ID (from the tenant platform)
* @param options.serverUrl - Base URL of the tenant platform, e.g. "https://dev.xuqinmin.com" * @param options.serverUrl - Base URL of the tenant platform, e.g. "http://192.168.116.9:8081"
* @param options.appKey - Optional; defaults to appId * @param options.appKey - Optional; defaults to appId
* @param options.debug - Enable verbose logging * @param options.debug - Enable verbose logging
*/ */
@ -38,7 +38,7 @@ export const XuqmSDK = {
* Kept for backward compatibility; prefer initialize() for production use. * Kept for backward compatibility; prefer initialize() for production use.
* *
* @param options.appId - Your application ID (from the tenant platform) * @param options.appId - Your application ID (from the tenant platform)
* @param options.serverUrl - Base URL of the tenant platform, e.g. "https://dev.xuqinmin.com" * @param options.serverUrl - Base URL of the tenant platform, e.g. "http://192.168.116.9:8081"
* @param options.appKey - Optional; defaults to appId * @param options.appKey - Optional; defaults to appId
* @param options.debug - Enable verbose logging * @param options.debug - Enable verbose logging
*/ */

查看文件

@ -2,6 +2,7 @@
"name": "@xuqm/rn-im", "name": "@xuqm/rn-im",
"version": "0.2.0", "version": "0.2.0",
"description": "XuqmGroup RN SDK — IM module (single chat, group chat, 13 message types)", "description": "XuqmGroup RN SDK — IM module (single chat, group chat, 13 message types)",
"license": "UNLICENSED",
"main": "src/index.ts", "main": "src/index.ts",
"react-native": "src/index.ts", "react-native": "src/index.ts",
"types": "src/index.ts", "types": "src/index.ts",

查看文件

@ -44,6 +44,15 @@ export async function uploadFile(
} as unknown as Blob) } 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`, { const response = await fetch(`${config.fileServiceUrl}/api/file/upload`, {
method: 'POST', method: 'POST',
headers: { headers: {
@ -55,10 +64,23 @@ export async function uploadFile(
if (!response.ok) { if (!response.ok) {
const text = await response.text().catch(() => '') 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}`) throw new Error(`[uploadFile] Upload failed (${response.status}): ${text}`)
} }
const json = await response.json() 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 } // Server wraps result in ApiResponse { code, data, message }
const data = json?.data ?? json const data = json?.data ?? json

查看文件

@ -2,6 +2,7 @@
"name": "@xuqm/rn-push", "name": "@xuqm/rn-push",
"version": "0.2.0", "version": "0.2.0",
"description": "XuqmGroup RN SDK — Push module (device token registration)", "description": "XuqmGroup RN SDK — Push module (device token registration)",
"license": "UNLICENSED",
"main": "src/index.ts", "main": "src/index.ts",
"react-native": "src/index.ts", "react-native": "src/index.ts",
"types": "src/index.ts", "types": "src/index.ts",

查看文件

@ -2,6 +2,7 @@
"name": "@xuqm/rn-update", "name": "@xuqm/rn-update",
"version": "0.2.0", "version": "0.2.0",
"description": "XuqmGroup RN SDK — Update module (App update, RN plugin hot-update)", "description": "XuqmGroup RN SDK — Update module (App update, RN plugin hot-update)",
"license": "UNLICENSED",
"main": "src/index.ts", "main": "src/index.ts",
"react-native": "src/index.ts", "react-native": "src/index.ts",
"types": "src/index.ts", "types": "src/index.ts",