feat(sdk): 初始化 Android SDK 核心功能模块
- 添加 SDK 配置管理、网络请求客户端和令牌存储功能 - 实现即时通讯 IM 模块,包括消息收发、群组管理和会话功能 - 集成推送服务和应用更新功能模块 - 创建示例应用演示 SDK 使用方法 - 配置项目依赖管理和构建设置
这个提交包含在:
父节点
bfecb15f55
当前提交
491a1ce8d3
@ -24,7 +24,7 @@ export default defineConfig({
|
||||
],
|
||||
},
|
||||
{ text: 'API 速查', link: '/server/api' },
|
||||
{ text: '平台控制台', link: 'https://sentry.xuqinmin.com', target: '_blank' },
|
||||
{ text: '平台控制台', link: 'https://dev.xuqinmin.com', target: '_blank' },
|
||||
],
|
||||
|
||||
sidebar: {
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
# Android SDK 概览
|
||||
# Android SDK 接入指南
|
||||
|
||||
**版本**:0.1.0 · **最低 Android 版本**:API 24 (Android 7.0) · **语言**:Kotlin
|
||||
**版本**:0.2.x(v0.4.0 将引入 UserSig 鉴权)· **最低 Android 版本**:API 24 (Android 7.0) · **语言**:Kotlin
|
||||
|
||||
> **注意**:v0.4.0 将是 Breaking 版本,`initialize()` 将保持不变,`ImSDK.login()` 将改为 UserSig 鉴权模式。
|
||||
|
||||
## 功能模块
|
||||
|
||||
| 模块 | Artifact | 功能 |
|
||||
|------|----------|------|
|
||||
| sdk-core | `com.xuqm:sdk-core` | 初始化、网络、鉴权、设备信息 |
|
||||
| sdk-im | `com.xuqm:sdk-im` | 单聊、群聊、消息收发 |
|
||||
| sdk-push | `com.xuqm:sdk-push` | 设备 Token 注册、离线推送 |
|
||||
| sdk-core | `com.xuqm:sdk-core` | 初始化、网络、鉴权(EncryptedSharedPreferences)|
|
||||
| sdk-im | `com.xuqm:sdk-im` | 单聊、群聊、消息收发、会话、好友、群组 |
|
||||
| sdk-push | `com.xuqm:sdk-push` | 自动检测厂商、设备 Token 注册 |
|
||||
| sdk-update | `com.xuqm:sdk-update` | App 更新检查、RN 热更新 |
|
||||
|
||||
## 快速接入
|
||||
@ -28,40 +30,39 @@ dependencyResolutionManagement {
|
||||
```kotlin
|
||||
// app/build.gradle.kts
|
||||
dependencies {
|
||||
implementation("com.xuqm:sdk-core:0.1.0")
|
||||
implementation("com.xuqm:sdk-im:0.1.0") // 按需
|
||||
implementation("com.xuqm:sdk-update:0.1.0") // 按需
|
||||
implementation("com.xuqm:sdk-core:0.2.0")
|
||||
implementation("com.xuqm:sdk-im:0.2.0")
|
||||
implementation("com.xuqm:sdk-push:0.2.0") // 按需
|
||||
implementation("com.xuqm:sdk-update:0.2.0") // 按需
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 初始化
|
||||
|
||||
只需传入 `appId`,服务器地址由 SDK 内置,**无需传 `serverUrl`**。
|
||||
|
||||
```kotlin
|
||||
// Application.onCreate()
|
||||
XuqmSDK.init(
|
||||
XuqmSDK.initialize(
|
||||
context = this,
|
||||
appKey = "your_app_id",
|
||||
appSecret = "your_app_secret", // 建议由服务端签发临时凭证
|
||||
apiBaseUrl = "https://sentry.xuqinmin.com",
|
||||
imBaseUrl = "wss://sentry.xuqinmin.com/ws/im",
|
||||
debug = BuildConfig.DEBUG
|
||||
appId = "your_app_id", // 在租户平台创建应用后获得
|
||||
logLevel = LogLevel.WARN, // 可选,DEBUG 开启详细日志
|
||||
)
|
||||
```
|
||||
|
||||
### 3. IM 登录与收消息
|
||||
|
||||
```kotlin
|
||||
// 先从你的服务端换取 IM Token,再登录
|
||||
ImSDK.login(
|
||||
appId = "your_app_id",
|
||||
userId = "user_001",
|
||||
nickname = "张三"
|
||||
)
|
||||
// 登录(协程 suspend 函数)
|
||||
lifecycleScope.launch {
|
||||
ImSDK.login(userId = "user_001", nickname = "张三")
|
||||
}
|
||||
|
||||
// 监听事件
|
||||
// 监听实时消息
|
||||
ImSDK.addListener(object : ImEventListener {
|
||||
override fun onConnected() { /* WebSocket 已连接 */ }
|
||||
override fun onMessage(msg: ImMessage) { /* 处理收到的消息 */ }
|
||||
override fun onMessage(msg: ImMessage) { /* 单聊消息 */ }
|
||||
override fun onGroupMessage(msg: ImMessage) { /* 群聊消息 */ }
|
||||
override fun onDisconnected(reason: String?) { /* 断线处理 */ }
|
||||
})
|
||||
```
|
||||
@ -69,12 +70,49 @@ ImSDK.addListener(object : ImEventListener {
|
||||
### 4. 发送消息
|
||||
|
||||
```kotlin
|
||||
// 发送文本(通过 WebSocket 实时发送)
|
||||
ImSDK.sendMessage(
|
||||
toId = "user_002",
|
||||
chatType = ChatType.SINGLE,
|
||||
msgType = MsgType.TEXT,
|
||||
content = "Hello!"
|
||||
chatType = "SINGLE",
|
||||
msgType = "TEXT",
|
||||
content = """{"text":"Hello!"}""",
|
||||
)
|
||||
```
|
||||
|
||||
[→ 完整安装配置](./setup) · [→ IM 接入详解](./im) · [→ API Reference](./api)
|
||||
### 5. 群组、好友、会话
|
||||
|
||||
```kotlin
|
||||
// 群组
|
||||
val groups = ImSDK.listGroups()
|
||||
val group = ImSDK.createGroup("项目讨论", listOf("user_002", "user_003"))
|
||||
ImSDK.addGroupMember(groupId, "user_004")
|
||||
ImSDK.leaveGroup(groupId)
|
||||
|
||||
// 好友
|
||||
val friends = ImSDK.listFriends()
|
||||
ImSDK.addFriend("user_002")
|
||||
|
||||
// 会话
|
||||
val conversations = ImSDK.listConversations()
|
||||
ImSDK.setConversationPinned(targetId, "SINGLE", true)
|
||||
ImSDK.markRead(targetId)
|
||||
```
|
||||
|
||||
### 6. 推送设备注册
|
||||
|
||||
```kotlin
|
||||
// 登录后调用;SDK 自动检测手机厂商(华为/小米/OPPO/vivo/荣耀)
|
||||
PushSDK.registerDevice(context, userId = "user_001")
|
||||
```
|
||||
|
||||
### 7. 版本更新
|
||||
|
||||
```kotlin
|
||||
// 检查 App 更新
|
||||
val update = UpdateSDK.checkAppUpdate(context)
|
||||
if (update?.needsUpdate == true) {
|
||||
UpdateSDK.downloadAndInstall(context, update.downloadUrl)
|
||||
}
|
||||
```
|
||||
|
||||
[→ 完整 API Reference](./api)
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
## 1. 注册账号与创建应用
|
||||
|
||||
1. 访问 [XuqmGroup 控制台](https://sentry.xuqinmin.com)
|
||||
1. 访问 [XuqmGroup 控制台](https://dev.xuqinmin.com)
|
||||
2. 注册租户账号,创建应用
|
||||
3. 记录 `appId`(即 `appKey`)
|
||||
|
||||
@ -23,8 +23,8 @@
|
||||
所有 SDK 均可直接连接演示环境验证功能:
|
||||
|
||||
```
|
||||
API 地址:https://sentry.xuqinmin.com
|
||||
WS 地址:wss://sentry.xuqinmin.com/ws/im
|
||||
API 地址:https://dev.xuqinmin.com
|
||||
WS 地址:wss://dev.xuqinmin.com/ws/im
|
||||
演示 AppId:ak_demo_chat
|
||||
演示用户:demo_alice / demo_bob
|
||||
```
|
||||
|
||||
@ -47,8 +47,8 @@ export default class EntryAbility extends UIAbility {
|
||||
appId: 'your_app_id',
|
||||
appKey: 'your_app_id',
|
||||
appSecret: 'your_app_secret',
|
||||
apiBaseUrl: 'https://sentry.xuqinmin.com',
|
||||
imWsUrl: 'wss://sentry.xuqinmin.com/ws/im',
|
||||
apiBaseUrl: 'https://dev.xuqinmin.com',
|
||||
imWsUrl: 'wss://dev.xuqinmin.com/ws/im',
|
||||
debug: true,
|
||||
})
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ hero:
|
||||
link: /guide/quickstart
|
||||
- theme: alt
|
||||
text: 平台控制台
|
||||
link: https://sentry.xuqinmin.com
|
||||
link: https://dev.xuqinmin.com
|
||||
|
||||
features:
|
||||
- icon: 🤖
|
||||
|
||||
@ -54,8 +54,8 @@ import XuqmCore
|
||||
XuqmSDK.shared.initialize(
|
||||
appKey: "your_app_id",
|
||||
appSecret: "your_app_secret",
|
||||
apiBaseUrl: "https://sentry.xuqinmin.com",
|
||||
imWsUrl: "wss://sentry.xuqinmin.com/ws/im",
|
||||
apiBaseUrl: "https://dev.xuqinmin.com",
|
||||
imWsUrl: "wss://dev.xuqinmin.com/ws/im",
|
||||
debug: false
|
||||
)
|
||||
```
|
||||
|
||||
@ -1,17 +1,23 @@
|
||||
# React Native SDK 概览
|
||||
# React Native SDK 接入指南
|
||||
|
||||
**包名**:`@xuqm/rn-sdk` · **版本**:0.3.0 · **支持**:React Native 0.73+
|
||||
**包名**:`@xuqm/rn-sdk` · **版本**:0.3.x(v0.4.0 规划中,将引入 UserSig 鉴权)
|
||||
|
||||
> **注意**:v0.4.0 将是 Breaking 版本。`initialize()` 将移除 `serverUrl` 参数,`login()` 将改为 UserSig 鉴权模式,详见[迁移指南](#迁移指南-v03x--v04x)。
|
||||
|
||||
---
|
||||
|
||||
## 功能模块
|
||||
|
||||
| 包 | 功能 |
|
||||
|----|------|
|
||||
| `@xuqm/rn-common` | 初始化、网络、设备信息(必须) |
|
||||
| `@xuqm/rn-im` | 单聊、群聊、消息收发、本地 DB |
|
||||
| `@xuqm/rn-im` | 单聊、群聊、消息收发、本地 DB(WatermelonDB)|
|
||||
| `@xuqm/rn-push` | 推送设备 Token 上报 |
|
||||
| `@xuqm/rn-update` | App 版本检查、RN Bundle 热更新 |
|
||||
| `@xuqm/rn-sdk` | 以上所有模块的 meta 包(推荐直接使用) |
|
||||
|
||||
---
|
||||
|
||||
## 安装
|
||||
|
||||
在项目根目录创建 `.npmrc`:
|
||||
@ -26,207 +32,249 @@
|
||||
yarn add @xuqm/rn-sdk
|
||||
```
|
||||
|
||||
或按需安装(减小包体积):
|
||||
---
|
||||
|
||||
```bash
|
||||
yarn add @xuqm/rn-common @xuqm/rn-im
|
||||
```
|
||||
## 快速接入(当前 v0.3.x)
|
||||
|
||||
## 快速接入
|
||||
### 1. 初始化
|
||||
|
||||
### 1. 初始化(推荐异步方式)
|
||||
初始化只需传入 `appId`,服务器地址由 SDK 内置,**不需要传 `serverUrl`**。
|
||||
|
||||
```ts
|
||||
import { XuqmSDK } from '@xuqm/rn-sdk'
|
||||
|
||||
// 推荐:从租户平台拉取完整配置
|
||||
// App 入口(如 App.tsx 的顶层)
|
||||
await XuqmSDK.initialize({
|
||||
appId: 'your_app_id',
|
||||
serverUrl: 'https://your-server.com',
|
||||
debug: __DEV__,
|
||||
})
|
||||
|
||||
// 兼容:同步初始化,不发网络请求,根据 serverUrl 推导 URL
|
||||
XuqmSDK.init({
|
||||
appId: 'your_app_id',
|
||||
serverUrl: 'https://your-server.com',
|
||||
appId: 'your_app_id', // 在租户平台创建应用后获得
|
||||
logLevel: __DEV__ ? 'debug' : 'warn', // 可选
|
||||
})
|
||||
```
|
||||
|
||||
> `initialize` 自动从 `GET /api/sdk/config?appId=` 获取 imWsUrl、fileServiceUrl 等配置,并在网络失败时 fallback 到 serverUrl 推导值。
|
||||
> SDK 内部自动处理服务器地址、WebSocket 连接、文件服务等配置,开发者无需关心。
|
||||
|
||||
### 2. IM 登录
|
||||
|
||||
```ts
|
||||
import { ImSDK } from '@xuqm/rn-sdk'
|
||||
|
||||
// 使用 IM token(由你的业务服务端签发)
|
||||
await ImSDK.loginWithToken('user_001', 'im_token_from_server', 'xuqm_im')
|
||||
// 登录(userId + 用户信息)
|
||||
// v0.3.x:传入用户信息,本地 DB 按 userId 自动隔离
|
||||
await ImSDK.login('user_001', 'nickname', 'https://avatar.url')
|
||||
|
||||
// 直接登录(适用于 im-service 直接认证场景)
|
||||
await ImSDK.login('user_001', '张三', 'https://cdn.example.com/avatar.jpg', 'xuqm_im')
|
||||
// 推荐提前在您的服务端生成 UserSig(v0.4.0 正式采用)
|
||||
// const userSig = await yourApi.getUserSig(userId)
|
||||
// await ImSDK.login('user_001', userSig)
|
||||
```
|
||||
|
||||
### 3. 监听消息与连接状态
|
||||
### 3. 消息收发
|
||||
|
||||
```ts
|
||||
import type { ImEventListener } from '@xuqm/rn-sdk'
|
||||
|
||||
const listener: ImEventListener = {
|
||||
onConnected() { console.log('WS 已连接') },
|
||||
onDisconnected(reason) { console.log('WS 断开:', reason) },
|
||||
onMessage(msg) { /* 收到单聊消息 */ },
|
||||
onGroupMessage(msg) { /* 收到群聊消息 */ },
|
||||
onError(err) { console.error(err) },
|
||||
}
|
||||
|
||||
ImSDK.addListener(listener)
|
||||
return () => ImSDK.removeListener(listener)
|
||||
```
|
||||
|
||||
### 4. 发送消息
|
||||
|
||||
```ts
|
||||
// 文本消息
|
||||
const msg = await ImSDK.sendMessage('user_002', 'SINGLE', 'TEXT', 'Hello!')
|
||||
|
||||
// 图片(SDK 自动上传到 file-service)
|
||||
const msg = await ImSDK.sendImageMessage('user_002', 'SINGLE', localUri, width, height)
|
||||
|
||||
// 视频
|
||||
const msg = await ImSDK.sendVideoMessage('user_002', 'SINGLE', localUri, thumbnailUri, durationSeconds)
|
||||
|
||||
// 语音
|
||||
const msg = await ImSDK.sendAudioMessage('user_002', 'SINGLE', localUri, durationSeconds)
|
||||
|
||||
// 文件
|
||||
const msg = await ImSDK.sendFileMessage('user_002', 'SINGLE', localUri, 'report.pdf', fileSize)
|
||||
```
|
||||
|
||||
### 5. 拉取历史消息
|
||||
|
||||
```ts
|
||||
// 单聊历史(先读本地 DB,再回源服务端)
|
||||
const history = await ImSDK.fetchHistory('user_002', 0, 30)
|
||||
|
||||
// 群聊历史
|
||||
const gHistory = await ImSDK.fetchGroupHistory(groupId, 0, 30)
|
||||
```
|
||||
|
||||
### 6. 会话列表(响应式)
|
||||
|
||||
```ts
|
||||
// 订阅本地 DB 变更,新消息/已读/静音/置顶都会触发回调
|
||||
const unsub = ImSDK.subscribeConversations((convs) => {
|
||||
setConversations(convs)
|
||||
// 监听实时消息
|
||||
ImSDK.addEventListener('message', (msg) => {
|
||||
console.log('收到消息:', msg.msgType, msg.content)
|
||||
})
|
||||
return unsub // 组件卸载时调用
|
||||
|
||||
// 发送文本消息
|
||||
const msg = await ImSDK.sendMessage(
|
||||
'user_002', // toId
|
||||
'SINGLE', // chatType: 'SINGLE' | 'GROUP'
|
||||
'TEXT', // msgType
|
||||
'Hello!' // content
|
||||
)
|
||||
|
||||
// 发送图片(自动上传到 file-service)
|
||||
const msg = await ImSDK.sendImageMessage(
|
||||
'user_002', 'SINGLE',
|
||||
'/path/to/image.jpg', // 本地 URI
|
||||
800, 600 // 宽高(可选)
|
||||
)
|
||||
|
||||
// 获取历史消息(单聊)
|
||||
const history = await ImSDK.fetchHistory('user_002', page, size)
|
||||
|
||||
// 获取群历史消息
|
||||
const groupHistory = await ImSDK.fetchGroupHistory('group_xxx', page, size)
|
||||
```
|
||||
|
||||
### 4. 会话列表
|
||||
|
||||
```ts
|
||||
// 订阅会话变化
|
||||
const unsub = ImSDK.subscribeConversations((conversations) => {
|
||||
// conversations: ConversationData[]
|
||||
console.log(conversations)
|
||||
})
|
||||
|
||||
// 置顶会话
|
||||
await ImSDK.setConversationPinned('user_002', 'SINGLE', true)
|
||||
|
||||
// 免打扰
|
||||
await ImSDK.setConversationMuted('group_xxx', 'GROUP', true)
|
||||
|
||||
// 标记已读
|
||||
await ImSDK.markRead('user_002')
|
||||
|
||||
// 置顶/静音
|
||||
await ImSDK.setConversationPinned('user_002', 'SINGLE', true)
|
||||
await ImSDK.setConversationMuted('user_002', 'SINGLE', true)
|
||||
```
|
||||
|
||||
### 7. 群聊
|
||||
### 5. 群组管理
|
||||
|
||||
```ts
|
||||
// 创建群
|
||||
const group = await ImSDK.createGroup('讨论组', ['user_001', 'user_002'])
|
||||
// 创建群组
|
||||
const group = await ImSDK.createGroup('项目讨论', ['user_002', 'user_003'])
|
||||
|
||||
// 订阅群消息 WebSocket topic
|
||||
ImSDK.subscribeGroup(group.id)
|
||||
// 群组列表(仅返回当前用户所在的群)
|
||||
const groups = await ImSDK.listGroups()
|
||||
|
||||
// 群消息撤回
|
||||
await ImSDK.revokeMessage(messageId)
|
||||
// 添加成员
|
||||
await ImSDK.addGroupMember('group_xxx', 'user_004')
|
||||
|
||||
// 移除成员(需要管理员权限)
|
||||
await ImSDK.removeGroupMember('group_xxx', 'user_004')
|
||||
|
||||
// 退出群聊
|
||||
await ImSDK.leaveGroup('group_xxx')
|
||||
```
|
||||
|
||||
### 8. 好友管理
|
||||
### 6. 好友关系
|
||||
|
||||
```ts
|
||||
await ImSDK.addFriend('user_002')
|
||||
await ImSDK.removeFriend('user_002')
|
||||
// 好友列表
|
||||
const friends = await ImSDK.listFriends()
|
||||
|
||||
// 添加好友(双向)
|
||||
await ImSDK.addFriend('user_002')
|
||||
|
||||
// 删除好友(双向)
|
||||
await ImSDK.removeFriend('user_002')
|
||||
```
|
||||
|
||||
### 9. 消息搜索
|
||||
### 7. 消息搜索(本地)
|
||||
|
||||
```ts
|
||||
const results = await ImSDK.searchMessages({
|
||||
keyword: '关键字',
|
||||
msgType: 'TEXT', // 可选,过滤消息类型
|
||||
startTime: '2026-01-01', // 可选,时间范围
|
||||
endTime: '2026-12-31',
|
||||
})
|
||||
import { ImSDK } from '@xuqm/rn-sdk'
|
||||
import type { MessageSearchParams } from '@xuqm/rn-sdk'
|
||||
|
||||
const params: MessageSearchParams = {
|
||||
keyword: '会议', // 关键词搜索
|
||||
toId: 'user_002', // 限定会话(可选)
|
||||
chatType: 'SINGLE', // 限定类型(可选)
|
||||
msgTypes: ['TEXT'], // 限定消息类型(可选)
|
||||
limit: 20,
|
||||
}
|
||||
const results = await ImSDK.searchMessages(params)
|
||||
```
|
||||
|
||||
### 10. App 版本更新
|
||||
### 8. 推送 SDK
|
||||
|
||||
```ts
|
||||
import { PushSDK } from '@xuqm/rn-sdk'
|
||||
|
||||
// 初始化并注册设备(登录后调用)
|
||||
await PushSDK.initialize({ userId: 'user_001' })
|
||||
```
|
||||
|
||||
### 9. 版本更新 SDK
|
||||
|
||||
```ts
|
||||
import { UpdateSDK } from '@xuqm/rn-sdk'
|
||||
|
||||
// 自动读取原生版本码,无需传参
|
||||
const info = await UpdateSDK.checkAppUpdate()
|
||||
if (info?.needsUpdate) {
|
||||
console.log(info.versionName, info.forceUpdate, info.downloadUrl)
|
||||
// 检查 App 原生更新
|
||||
const appUpdate = await UpdateSDK.checkAppUpdate()
|
||||
if (appUpdate?.needsUpdate) {
|
||||
console.log('新版本:', appUpdate.versionName)
|
||||
// Linking.openURL(appUpdate.downloadUrl)
|
||||
}
|
||||
|
||||
// 检查 RN Bundle 热更新
|
||||
const rnUpdate = await UpdateSDK.checkRnUpdate('your_module_id')
|
||||
if (rnUpdate?.needsUpdate) {
|
||||
await UpdateSDK.downloadAndApplyBundle(rnUpdate)
|
||||
}
|
||||
```
|
||||
|
||||
### 11. RN Bundle 热更新
|
||||
### 10. 断开连接
|
||||
|
||||
```ts
|
||||
// 插件在 bundle 加载时自注册(自动读取 plugin.json)
|
||||
import meta from './plugin.json' // { moduleId, version }
|
||||
UpdateSDK.registerPlugin(meta)
|
||||
|
||||
// 检查 → 下载 → 缓存(三步)
|
||||
const checkInfo = await UpdateSDK.checkRnUpdate('home')
|
||||
if (checkInfo.needsUpdate) {
|
||||
const source = await UpdateSDK.downloadRnBundle(checkInfo.downloadUrl)
|
||||
await UpdateSDK.cacheRnBundle('home', checkInfo.latestVersion, checkInfo.md5, source)
|
||||
}
|
||||
ImSDK.disconnect()
|
||||
```
|
||||
|
||||
## 消息类型 content 格式
|
||||
---
|
||||
|
||||
| MsgType | content |
|
||||
|---------|---------|
|
||||
| `TEXT` | 纯文本字符串 |
|
||||
| `IMAGE` | `{"url":"...","thumbnailUrl":"...","width":800,"height":600}` |
|
||||
| `VIDEO` | `{"url":"...","thumbnailUrl":"...","duration":30,"size":1048576}` |
|
||||
| `AUDIO` | `{"url":"...","duration":12,"size":204800}` |
|
||||
| `FILE` | `{"url":"...","name":"report.pdf","size":512000,"mimeType":"application/pdf"}` |
|
||||
| `LOCATION` | `{"lat":39.9042,"lng":116.4074,"address":"北京市","title":"天安门"}` |
|
||||
| `CUSTOM` | 任意 JSON 字符串 |
|
||||
| `NOTIFY` | `{"title":"系统通知","content":"内容","level":"INFO"}` |
|
||||
| `RICH_TEXT` | `{"html":"<b>加粗</b>内容"}` |
|
||||
|
||||
## TypeScript 类型
|
||||
## TypeScript 类型参考
|
||||
|
||||
```ts
|
||||
// 消息
|
||||
interface ImMessage {
|
||||
id: string
|
||||
appId: string
|
||||
fromUserId: string
|
||||
toId: string
|
||||
chatType: 'SINGLE' | 'GROUP'
|
||||
msgType: MsgType
|
||||
content: string
|
||||
status: 'SENT' | 'DELIVERED' | 'READ' | 'REVOKED'
|
||||
mentionedUserIds?: string
|
||||
createdAt: string // ISO 8601
|
||||
id: string
|
||||
fromId: string
|
||||
toId: string
|
||||
chatType: 'SINGLE' | 'GROUP'
|
||||
msgType: 'TEXT' | 'IMAGE' | 'AUDIO' | 'VIDEO' | 'FILE' |
|
||||
'LOCATION' | 'NOTIFY' | 'CUSTOM' | 'RICH_TEXT' |
|
||||
'CALL_AUDIO' | 'CALL_VIDEO' | 'FORWARD' | 'REVOKED'
|
||||
content: string // JSON 字符串,结构按 msgType 不同
|
||||
status: 'SENDING' | 'SENT' | 'DELIVERED' | 'READ' | 'FAILED' | 'REVOKED'
|
||||
createdAt: number // Unix 毫秒
|
||||
}
|
||||
|
||||
// 会话
|
||||
interface ConversationData {
|
||||
targetId: string
|
||||
chatType: 'SINGLE' | 'GROUP'
|
||||
targetId: string
|
||||
chatType: 'SINGLE' | 'GROUP'
|
||||
lastMsgContent: string
|
||||
lastMsgType: string
|
||||
lastMsgTime: number // Unix ms
|
||||
unreadCount: number
|
||||
isMuted: boolean
|
||||
isPinned: boolean
|
||||
lastMsgType: string
|
||||
lastMsgTime: number
|
||||
unreadCount: number
|
||||
isMuted: boolean
|
||||
isPinned: boolean
|
||||
}
|
||||
|
||||
// 群组
|
||||
interface ImGroup {
|
||||
id: string
|
||||
name: string
|
||||
creatorId: string
|
||||
memberIds: string // JSON 数组字符串
|
||||
adminIds: string
|
||||
createdAt: number
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 迁移指南(v0.3.x → v0.4.0)
|
||||
|
||||
v0.4.0 预计改动(**Breaking Changes**):
|
||||
|
||||
```diff
|
||||
// 初始化
|
||||
- await XuqmSDK.initialize({ appId: 'xxx', serverUrl: 'https://...' })
|
||||
+ await XuqmSDK.initialize({ appId: 'xxx' }) // serverUrl 内置,无需传入
|
||||
|
||||
// IM 登录(改为 UserSig 鉴权,密码不再传入 SDK)
|
||||
- await ImSDK.login(userId, nickname, avatar, dbName)
|
||||
+ const userSig = await yourServer.getUserSig(userId) // 您的服务端签发
|
||||
+ await ImSDK.login(userId, userSig, { nickname, avatar })
|
||||
// dbName 自动由 appId + userId 派生,无需传入
|
||||
|
||||
// loginWithToken 废弃
|
||||
- await ImSDK.loginWithToken(userId, token, dbName)
|
||||
+ // 统一使用 login(userId, userSig)
|
||||
```
|
||||
|
||||
UserSig 生成方式见[安全设计文档](../../design/02-security-design.md)。
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
**Q: 如何获取 appId?**
|
||||
在 [租户平台](https://dev.xuqinmin.com) 注册账号后,创建应用即可获得 AppId。
|
||||
|
||||
**Q: 为什么不需要传 serverUrl?**
|
||||
XuqmGroup 是托管平台,服务地址统一管理,与腾讯云 IM 等平台的设计一致,开发者只需关心业务逻辑。
|
||||
|
||||
**Q: UserSig 是什么?(v0.4.0)**
|
||||
UserSig 是您的业务服务端用 AppSecret 为用户签发的安全凭证,有效期可配置。AppSecret 绝不下发到客户端。
|
||||
|
||||
**Q: 本地消息存储在哪里?**
|
||||
使用 WatermelonDB(SQLite),按 `appId + userId` 自动隔离,多账号切换安全。
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Server API 参考
|
||||
|
||||
**Base URL**:`https://sentry.xuqinmin.com`
|
||||
**Base URL**:`https://dev.xuqinmin.com`
|
||||
|
||||
所有 API 通过 Nginx 反代,无需区分内部端口。
|
||||
|
||||
|
||||
@ -38,8 +38,8 @@ app.use(createXuqm({
|
||||
appId: 'your_app_id',
|
||||
appKey: 'your_app_id',
|
||||
appSecret: 'your_app_secret',
|
||||
apiBaseUrl: 'https://sentry.xuqinmin.com',
|
||||
imWsUrl: 'wss://sentry.xuqinmin.com/ws/im',
|
||||
apiBaseUrl: 'https://dev.xuqinmin.com',
|
||||
imWsUrl: 'wss://dev.xuqinmin.com/ws/im',
|
||||
debug: import.meta.env.DEV,
|
||||
}))
|
||||
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
| 系统 | 地址 | 说明 |
|
||||
|------|------|------|
|
||||
| 租户开放平台 | `https://sentry.xuqinmin.com/` | 主账号注册、登录、应用管理 |
|
||||
| 运营管理平台 | `https://sentry.xuqinmin.com/ops/` | 内部运营管理入口 |
|
||||
| 租户开放平台 | `https://dev.xuqinmin.com/` | 主账号注册、登录、应用管理 |
|
||||
| 运营管理平台 | `https://dev.xuqinmin.com/ops/` | 内部运营管理入口 |
|
||||
|
||||
## 初始化管理员账号
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
|
||||
| 平台 | API Base |
|
||||
|------|----------|
|
||||
| tenant-platform | `https://sentry.xuqinmin.com/api` |
|
||||
| ops-platform | `https://sentry.xuqinmin.com/api` |
|
||||
| tenant-platform | `https://dev.xuqinmin.com/api` |
|
||||
| ops-platform | `https://dev.xuqinmin.com/api` |
|
||||
|
||||
## 主要页面
|
||||
|
||||
@ -74,5 +74,5 @@
|
||||
## 环境变量
|
||||
|
||||
```env
|
||||
VITE_API_BASE_URL=https://sentry.xuqinmin.com/api
|
||||
VITE_API_BASE_URL=https://dev.xuqinmin.com/api
|
||||
```
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const imClient = axios.create({
|
||||
baseURL: 'https://sentry.xuqinmin.com',
|
||||
baseURL: 'https://dev.xuqinmin.com',
|
||||
timeout: 15000,
|
||||
})
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const updateClient = axios.create({
|
||||
baseURL: 'https://sentry.xuqinmin.com',
|
||||
baseURL: 'https://dev.xuqinmin.com',
|
||||
timeout: 30000,
|
||||
})
|
||||
|
||||
|
||||
正在加载...
在新工单中引用
屏蔽一个用户