diff --git a/Dockerfile b/Dockerfile index dd7ecdd..07ac4e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,7 @@ COPY package.json ./package.json COPY yarn.lock ./yarn.lock COPY tenant-platform ./tenant-platform COPY ops-platform ./ops-platform +COPY docs-site ./docs-site RUN yarn install --frozen-lockfile @@ -19,7 +20,10 @@ RUN cd tenant-platform && \ RUN cd ops-platform && \ VITE_APP_BASE=${OPS_APP_BASE} VITE_API_BASE_URL=${OPS_API_BASE_URL} yarn build +RUN cd docs-site && yarn build + FROM nginx:1.27-alpine COPY nginx/default.conf /etc/nginx/conf.d/default.conf COPY --from=build /workspace/tenant-platform/dist /usr/share/nginx/html/tenant COPY --from=build /workspace/ops-platform/dist /usr/share/nginx/html/ops +COPY --from=build /workspace/docs-site/docs/.vitepress/dist /usr/share/nginx/html/docs diff --git a/docs-site/docs/.vitepress/config.ts b/docs-site/docs/.vitepress/config.ts new file mode 100644 index 0000000..4eeac48 --- /dev/null +++ b/docs-site/docs/.vitepress/config.ts @@ -0,0 +1,88 @@ +import { defineConfig } from 'vitepress' + +export default defineConfig({ + title: 'XuqmGroup 开发者文档', + description: 'XuqmGroup 多端 SDK 接入指南', + base: '/docs/', + lang: 'zh-CN', + + themeConfig: { + logo: '/logo.svg', + siteTitle: 'XuqmGroup Dev Docs', + + nav: [ + { text: '快速开始', link: '/guide/quickstart' }, + { + text: 'SDK', + items: [ + { text: 'Android', link: '/android/' }, + { text: 'iOS', link: '/ios/' }, + { text: 'React Native', link: '/rn/' }, + { text: 'Vue3', link: '/vue3/' }, + { text: 'HarmonyOS', link: '/harmony/' }, + ], + }, + { text: 'API 速查', link: '/server/api' }, + { text: '平台控制台', link: 'https://sentry.xuqinmin.com', target: '_blank' }, + ], + + sidebar: { + '/guide/': [ + { text: '快速开始', link: '/guide/quickstart' }, + { text: '平台概念', link: '/guide/concepts' }, + { text: '接入流程', link: '/guide/flow' }, + ], + '/android/': [ + { text: '概览', link: '/android/' }, + { text: '安装配置', link: '/android/setup' }, + { text: 'IM 接入', link: '/android/im' }, + { text: '推送接入', link: '/android/push' }, + { text: '版本管理', link: '/android/update' }, + { text: 'API Reference', link: '/android/api' }, + ], + '/ios/': [ + { text: '概览', link: '/ios/' }, + { text: '安装配置', link: '/ios/setup' }, + { text: 'IM 接入', link: '/ios/im' }, + { text: '推送接入', link: '/ios/push' }, + { text: '版本管理', link: '/ios/update' }, + { text: 'API Reference', link: '/ios/api' }, + ], + '/rn/': [ + { text: '概览', link: '/rn/' }, + { text: '安装配置', link: '/rn/setup' }, + { text: 'IM 接入', link: '/rn/im' }, + { text: '群聊', link: '/rn/group' }, + { text: '版本管理', link: '/rn/update' }, + { text: 'API Reference', link: '/rn/api' }, + ], + '/vue3/': [ + { text: '概览', link: '/vue3/' }, + { text: '安装配置', link: '/vue3/setup' }, + { text: 'IM 接入', link: '/vue3/im' }, + { text: 'API Reference', link: '/vue3/api' }, + ], + '/harmony/': [ + { text: '概览', link: '/harmony/' }, + { text: '安装配置', link: '/harmony/setup' }, + { text: 'IM 接入', link: '/harmony/im' }, + ], + '/server/': [ + { text: 'API 速查', link: '/server/api' }, + { text: 'WebSocket', link: '/server/websocket' }, + { text: '错误码', link: '/server/errors' }, + ], + }, + + socialLinks: [ + { icon: 'github', link: 'https://xuqinmin.com/xuqinmin12' }, + ], + + footer: { + message: 'XuqmGroup 开放平台', + copyright: 'Copyright © 2026 XuqmGroup', + }, + + search: { provider: 'local' }, + }, +}) diff --git a/docs-site/docs/android/index.md b/docs-site/docs/android/index.md new file mode 100644 index 0000000..e4f750c --- /dev/null +++ b/docs-site/docs/android/index.md @@ -0,0 +1,80 @@ +# Android SDK 概览 + +**版本**:0.1.0 · **最低 Android 版本**:API 24 (Android 7.0) · **语言**:Kotlin + +## 功能模块 + +| 模块 | Artifact | 功能 | +|------|----------|------| +| sdk-core | `com.xuqm:sdk-core` | 初始化、网络、鉴权、设备信息 | +| sdk-im | `com.xuqm:sdk-im` | 单聊、群聊、消息收发 | +| sdk-push | `com.xuqm:sdk-push` | 设备 Token 注册、离线推送 | +| sdk-update | `com.xuqm:sdk-update` | App 更新检查、RN 热更新 | + +## 快速接入 + +### 1. 添加依赖 + +```kotlin +// settings.gradle.kts +dependencyResolutionManagement { + repositories { + maven("https://nexus.xuqinmin.com/repository/android/") + google(); mavenCentral() + } +} +``` + +```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") // 按需 +} +``` + +### 2. 初始化 + +```kotlin +// Application.onCreate() +XuqmSDK.init( + 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 +) +``` + +### 3. IM 登录与收消息 + +```kotlin +// 先从你的服务端换取 IM Token,再登录 +ImSDK.login( + appId = "your_app_id", + userId = "user_001", + nickname = "张三" +) + +// 监听事件 +ImSDK.addListener(object : ImEventListener { + override fun onConnected() { /* WebSocket 已连接 */ } + override fun onMessage(msg: ImMessage) { /* 处理收到的消息 */ } + override fun onDisconnected(reason: String?) { /* 断线处理 */ } +}) +``` + +### 4. 发送消息 + +```kotlin +ImSDK.sendMessage( + toId = "user_002", + chatType = ChatType.SINGLE, + msgType = MsgType.TEXT, + content = "Hello!" +) +``` + +[→ 完整安装配置](./setup) · [→ IM 接入详解](./im) · [→ API Reference](./api) diff --git a/docs-site/docs/guide/quickstart.md b/docs-site/docs/guide/quickstart.md new file mode 100644 index 0000000..dbab2e5 --- /dev/null +++ b/docs-site/docs/guide/quickstart.md @@ -0,0 +1,46 @@ +# 快速开始 + +5 分钟接入 XuqmGroup IM,实现消息收发。 + +## 1. 注册账号与创建应用 + +1. 访问 [XuqmGroup 控制台](https://sentry.xuqinmin.com) +2. 注册租户账号,创建应用 +3. 记录 `appId`(即 `appKey`) + +## 2. 选择你的平台 + +| 平台 | 推荐接入方式 | +|------|------------| +| Android | [Android SDK →](/android/) | +| iOS | [iOS SDK →](/ios/) | +| React Native | [RN SDK →](/rn/) | +| Vue3 / Web | [Vue3 SDK →](/vue3/) | +| HarmonyOS | [HarmonyOS SDK →](/harmony/) | + +## 3. 演示环境 + +所有 SDK 均可直接连接演示环境验证功能: + +``` +API 地址:https://sentry.xuqinmin.com +WS 地址:wss://sentry.xuqinmin.com/ws/im +演示 AppId:ak_demo_chat +演示用户:demo_alice / demo_bob +``` + +## 4. 接入流程 + +``` +你的业务服务端 + → 持有 appId/appSecret + → 调用 POST /api/im/auth/login?appId=&userId=&nickname= 换取 IM Token + → 返回 Token 给客户端 + +客户端 SDK + → 使用 Token 初始化 IM 连接 + → 建立 WebSocket 长连接 + → 开始收发消息 +``` + +> **安全提示**:appSecret 应仅在你的服务端持有,不应下发给客户端。 diff --git a/docs-site/docs/harmony/index.md b/docs-site/docs/harmony/index.md new file mode 100644 index 0000000..e037234 --- /dev/null +++ b/docs-site/docs/harmony/index.md @@ -0,0 +1,170 @@ +# HarmonyOS SDK 概览 + +**包名**:`@xuqm/harmony-sdk` · **版本**:0.1.0 · **支持**:HarmonyOS NEXT(API 12+)、ArkTS + +## 功能模块 + +| 模块 | 功能 | +|------|------| +| `XuqmSDK` | 全局初始化 | +| `ImSDK` | 单聊、群聊、消息收发 | +| `UpdateSDK` | App 版本检查、RN Bundle 热更新 | + +## 安装 + +在 `oh-package.json5` 中添加: + +```json +{ + "dependencies": { + "@xuqm/harmony-sdk": "0.1.0" + } +} +``` + +配置私有仓库(`.ohpmrc`): + +``` +registry=https://nexus.xuqinmin.com/repository/ohpm-hosted/ +``` + +执行安装: + +```bash +ohpm install +``` + +## 快速接入 + +### 1. 初始化(EntryAbility.onCreate) + +```typescript +import { XuqmSDK } from '@xuqm/harmony-sdk' + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + XuqmSDK.init({ + appId: 'your_app_id', + appKey: 'your_app_id', + appSecret: 'your_app_secret', + apiBaseUrl: 'https://sentry.xuqinmin.com', + imWsUrl: 'wss://sentry.xuqinmin.com/ws/im', + debug: true, + }) + } +} +``` + +### 2. IM 登录 + +```typescript +import { ImSDK } from '@xuqm/harmony-sdk' + +await ImSDK.login('user_001', '张三') +``` + +### 3. 监听消息 + +```typescript +ImSDK.addListener({ + onConnected(): void { console.log('WS connected') }, + onDisconnected(reason: string | null): void { }, + onMessage(msg: ImMessage): void { /* 处理消息 */ }, + onError(err: string): void { }, +}) +``` + +### 4. 发送消息 + +```typescript +// 文本消息 +const sent = await ImSDK.sendMessage({ + toId: 'user_002', + chatType: 'SINGLE', + msgType: 'TEXT', + content: 'Hello from HarmonyOS!', +}) + +// 图片消息 +const sent = await ImSDK.sendMessage({ + toId: 'user_002', chatType: 'SINGLE', + msgType: 'IMAGE', + content: JSON.stringify({ url: 'https://cdn.example.com/img.jpg', width: 800, height: 600 }), +}) +``` + +### 5. 撤回消息 + +```typescript +const revoked = await ImSDK.revokeMessage(msg.id) +``` + +### 6. 群聊 + +```typescript +const group = await ImSDK.createGroup('鸿蒙群', ['user_001', 'user_002']) +ImSDK.subscribeGroup(group.id) +const sent = await ImSDK.sendMessage({ toId: group.id, chatType: 'GROUP', msgType: 'TEXT', content: '大家好' }) +``` + +### 7. 检查更新 + +```typescript +import { UpdateSDK } from '@xuqm/harmony-sdk' + +const appInfo = await UpdateSDK.checkAppUpdate(1) +if (appInfo?.forceUpdate) { + // 跳转应用市场 +} + +const bundle = await UpdateSDK.checkRNUpdate('home', '1.0.0') +if (bundle) { + const content = await UpdateSDK.downloadBundle(bundle.downloadUrl) + // 缓存至本地,由 BundleRuntime 加载 +} +``` + +## ArkUI 示例 + +```typescript +@Component +struct ChatView { + @State messages: ImMessage[] = [] + + aboutToAppear() { + ImSDK.addListener({ + onMessage: (msg) => { this.messages = [...this.messages, msg] }, + onConnected: () => {}, + onDisconnected: () => {}, + onError: () => {}, + }) + } + + build() { + Column() { + List() { + ForEach(this.messages, (msg: ImMessage) => { + ListItem() { + Text(`${msg.fromUserId}: ${msg.content}`) + .fontSize(16) + .padding(8) + } + }) + } + } + } +} +``` + +## 权限配置 + +在 `module.json5` 中添加必要权限: + +```json +{ + "requestPermissions": [ + { "name": "ohos.permission.INTERNET" }, + { "name": "ohos.permission.GET_NETWORK_INFO" } + ] +} +``` diff --git a/docs-site/docs/index.md b/docs-site/docs/index.md new file mode 100644 index 0000000..0b92620 --- /dev/null +++ b/docs-site/docs/index.md @@ -0,0 +1,40 @@ +--- +layout: home +hero: + name: XuqmGroup + text: 开发者文档 + tagline: 多端 SDK 一站式接入指南 · IM · 推送 · 版本管理 + actions: + - theme: brand + text: 快速开始 + link: /guide/quickstart + - theme: alt + text: 平台控制台 + link: https://sentry.xuqinmin.com + +features: + - icon: 🤖 + title: Android SDK + details: Kotlin 优先,支持 IM 单聊/群聊、离线推送、整包/热更新 + link: /android/ + - icon: 🍎 + title: iOS SDK + details: Swift async/await,支持 IM、APNs 推送、版本管理 + link: /ios/ + - icon: ⚛️ + title: React Native SDK + details: TypeScript,支持全 12 种消息类型、群聊、热更新 + link: /rn/ + - icon: 💚 + title: Vue3 SDK + details: Composable API,useIm() 开箱即用 + link: /vue3/ + - icon: 🎵 + title: HarmonyOS SDK + details: ArkTS,支持 IM 和基础推送能力 + link: /harmony/ + - icon: 🔌 + title: 服务端 API + details: 完整 REST API 速查,WebSocket STOMP 协议说明 + link: /server/api +--- diff --git a/docs-site/docs/ios/index.md b/docs-site/docs/ios/index.md new file mode 100644 index 0000000..9b3fb4a --- /dev/null +++ b/docs-site/docs/ios/index.md @@ -0,0 +1,159 @@ +# iOS SDK 概览 + +**版本**:0.1.0 · **最低 iOS 版本**:iOS 14 · **语言**:Swift 5.9+ + +## 功能模块 + +| 模块 | 功能 | +|------|------| +| XuqmCore | 初始化、网络、鉴权 | +| XuqmIM | 单聊、群聊、消息收发(13 种类型)| +| XuqmPush | APNs 设备 Token 注册、通知处理 | +| XuqmUpdate | App 版本检查、RN Bundle 热更新 | + +## 安装 + +### Swift Package Manager(推荐) + +在 Xcode → File → Add Package Dependencies 中输入: + +``` +https://github.com/xuqm/XuqmGroup-iOSSDK +``` + +或在 `Package.swift` 中添加: + +```swift +dependencies: [ + .package(url: "https://github.com/xuqm/XuqmGroup-iOSSDK", from: "0.1.0") +] +``` + +按需引入所需模块: + +```swift +.target( + name: "MyApp", + dependencies: [ + .product(name: "XuqmCore", package: "XuqmGroup-iOSSDK"), + .product(name: "XuqmIM", package: "XuqmGroup-iOSSDK"), + .product(name: "XuqmUpdate", package: "XuqmGroup-iOSSDK"), + ] +) +``` + +## 快速接入 + +### 1. 初始化 + +在 `AppDelegate.application(_:didFinishLaunchingWithOptions:)` 中: + +```swift +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", + debug: false +) +``` + +### 2. IM 登录与监听消息 + +```swift +import XuqmIM + +// 登录(appId 已在 init 时指定) +try await ImSDK.shared.login(userId: "user_001", nickname: "张三") + +// 监听事件 +ImSDK.shared.addListener(self) + +extension ViewController: ImEventListener { + func onConnected() { print("WS connected") } + func onMessage(_ msg: ImMessage) { /* 处理消息 */ } + func onDisconnected(reason: String?) { /* 断线 */ } +} +``` + +### 3. 发送消息 + +```swift +// 发文本 +let sent = try await ImSDK.shared.sendMessage( + toId: "user_002", + chatType: .single, + msgType: .text, + content: "Hello!" +) + +// 发图片(content 为 JSON 字符串) +let imgContent = try JSONSerialization.data(withJSONObject: [ + "url": "https://cdn.example.com/img.jpg", + "width": 800, "height": 600 +]) +let sent = try await ImSDK.shared.sendMessage( + toId: "user_002", chatType: .single, + msgType: .image, content: String(data: imgContent, encoding: .utf8)! +) +``` + +### 4. 撤回消息 + +```swift +let revoked = try await ImSDK.shared.revokeMessage(messageId: msg.id) +``` + +### 5. 群聊 + +```swift +// 创建群组 +let group = try await ImSDK.shared.createGroup(name: "我的群", memberIds: ["user_001", "user_002"]) + +// 订阅群消息 +ImSDK.shared.subscribeGroup(groupId: group.id) + +// 发送群消息 +try await ImSDK.shared.sendMessage( + toId: group.id, chatType: .group, msgType: .text, content: "大家好" +) +``` + +### 6. 检查更新 + +```swift +import XuqmUpdate + +// App 整包更新 +let appInfo = try await UpdateSDK.shared.checkAppUpdate(currentVersionCode: 1) +if let info = appInfo, info.forceUpdate { + // 强制更新:跳转 App Store 或下载链接 + UIApplication.shared.open(URL(string: info.downloadUrl ?? info.appStoreUrl!)!) +} + +// RN Bundle 热更新 +let bundle = try await UpdateSDK.shared.checkRNUpdate(moduleId: "home", currentVersion: "1.0.0") +if let bundle = bundle { + let data = try await UpdateSDK.shared.downloadBundle(url: bundle.downloadUrl) + // 缓存至本地,下次启动时由 BundleRuntime 加载 +} +``` + +## 消息类型 + +| MsgType | 说明 | content 结构 | +|---------|------|-------------| +| `.text` | 纯文本 | `String` | +| `.image` | 图片 | `{url, width, height, thumbnailUrl?}` | +| `.video` | 视频 | `{url, duration, thumbnailUrl, size}` | +| `.audio` | 语音 | `{url, duration, size}` | +| `.file` | 文件 | `{url, name, size, mimeType}` | +| `.location` | 位置 | `{lat, lng, address, title}` | +| `.custom` | 自定义 | 任意 JSON | +| `.notify` | 系统通知 | `{title, content, level}` | +| `.richText` | 富文本 | `{html}` | +| `.callAudio` | 语音通话信令 | `{callId, action, callerName}` | +| `.callVideo` | 视频通话信令 | `{callId, action, callerName}` | +| `.forward` | 转发 | `{originalMsgId, originalContent, originalSender}` | diff --git a/docs-site/docs/rn/index.md b/docs-site/docs/rn/index.md new file mode 100644 index 0000000..69fd688 --- /dev/null +++ b/docs-site/docs/rn/index.md @@ -0,0 +1,209 @@ +# React Native SDK 概览 + +**包名**:`@xuqm/rn-sdk` · **版本**:0.1.0 · **支持**:React Native 0.73+、Expo 50+ + +## 功能模块 + +| 导出 | 功能 | +|------|------| +| `XuqmSDK` | 全局初始化 | +| `ImSDK` | 单聊、群聊、消息收发、历史记录 | +| `UpdateSDK` | App 版本检查、RN Bundle 热更新 | +| `PushSDK` | 设备 Token 上报 | + +## 安装 + +### 从 Nexus 私有仓库安装 + +在项目根目录创建 `.npmrc`: + +``` +@xuqm:registry=https://nexus.xuqinmin.com/repository/npm-hosted/ +``` + +然后安装: + +```bash +npm install @xuqm/rn-sdk +# 或 +yarn add @xuqm/rn-sdk +``` + +## 快速接入 + +### 1. 初始化(一次即可,在 App 启动时调用) + +```ts +import { XuqmSDK } from '@xuqm/rn-sdk' + +XuqmSDK.init({ + appId: 'your_app_id', + appKey: 'your_app_id', + appSecret: 'your_app_secret', + apiBaseUrl: 'https://sentry.xuqinmin.com', + imWsUrl: 'wss://sentry.xuqinmin.com/ws/im', + debug: __DEV__, +}) +``` + +### 2. IM 登录 + +```ts +import { ImSDK } from '@xuqm/rn-sdk' + +await ImSDK.login('user_001', '张三') +``` + +### 3. 监听消息与连接事件 + +```ts +import type { ImEventListener } from '@xuqm/rn-sdk' + +const listener: ImEventListener = { + onConnected() { console.log('WS connected') }, + onDisconnected(reason) { console.log('WS disconnected:', reason) }, + onMessage(msg) { /* 单聊/群聊消息 */ }, + onGroupMessage(msg) { /* 群消息(独立回调) */ }, + onError(err) { console.error(err) }, +} + +ImSDK.addListener(listener) + +// 组件卸载时移除 +return () => { + ImSDK.removeListener(listener) + ImSDK.disconnect() +} +``` + +### 4. 发送消息 + +```ts +// 文本 +const sent = await ImSDK.sendMessage('user_002', 'SINGLE', 'TEXT', 'Hello!') + +// 图片(content 为 JSON 字符串) +const sent = await ImSDK.sendMessage('user_002', 'SINGLE', 'IMAGE', JSON.stringify({ + url: 'https://cdn.example.com/img.jpg', + width: 800, height: 600, +})) +``` + +### 5. 撤回消息 + +```ts +const revoked = await ImSDK.revokeMessage(msg.id) +``` + +### 6. 拉取历史 + +```ts +// 单聊历史(page=0, size=50) +const history = await ImSDK.fetchHistory('user_002', 0, 50) + +// 群历史 +const gHistory = await ImSDK.fetchGroupHistory(groupId, 0, 50) +``` + +### 7. 群聊 + +```ts +// 创建群(自动将自己加入成员列表) +const group = await ImSDK.createGroup('开发讨论组', ['user_001', 'user_002']) + +// 订阅群 WebSocket topic +ImSDK.subscribeGroup(group.id) + +// 列出所有群 +const groups = await ImSDK.listGroups() + +// 发群消息 +const sent = await ImSDK.sendMessage(group.id, 'GROUP', 'TEXT', '大家好') +``` + +### 8. 检查 App 更新 + +```ts +import { UpdateSDK } from '@xuqm/rn-sdk' + +const info = await UpdateSDK.checkAppUpdate(1 /* 当前 versionCode */) +if (info) { + console.log(info.versionName, info.forceUpdate, info.downloadUrl) +} +``` + +### 9. RN Bundle 热更新(三步流程) + +```ts +import AsyncStorage from '@react-native-async-storage/async-storage' + +// Step 1: 检查是否有新版本 +const bundle = await UpdateSDK.checkRNUpdate('home', '1.0.0') +if (!bundle) return // 已是最新 + +// Step 2: 下载 bundle +const content = await UpdateSDK.downloadBundle(bundle.downloadUrl) + +// Step 3: 缓存,下次启动由 BundleRuntime 加载 +await AsyncStorage.setItem('rn_bundle_home', JSON.stringify({ + version: bundle.version, + md5: bundle.md5, + content, + cachedAt: new Date().toISOString(), +})) +``` + +> **提示**:运行时替换(热加载)需对接原生 `BundleRuntime`,参考 `ProjectFrameReactNative` 架构文档。 + +## 完整消息类型 + +```ts +type MsgType = + | 'TEXT' | 'IMAGE' | 'VIDEO' | 'AUDIO' | 'FILE' + | 'CUSTOM' | 'LOCATION' | 'NOTIFY' | 'RICH_TEXT' + | 'CALL_AUDIO' | 'CALL_VIDEO' | 'FORWARD' | 'REVOKED' +``` + +每种类型的 `content` 格式: + +| MsgType | content | +|---------|---------| +| `TEXT` | 纯文本字符串 | +| `IMAGE` | `{"url":"...","width":800,"height":600,"thumbnailUrl":"..."}` | +| `VIDEO` | `{"url":"...","duration":30,"thumbnailUrl":"...","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":"加粗内容"}` | +| `CALL_AUDIO` | `{"callId":"uuid","action":"INVITE","callerName":"张三"}` | +| `CALL_VIDEO` | `{"callId":"uuid","action":"INVITE","callerName":"张三"}` | +| `FORWARD` | `{"originalMsgId":"...","originalContent":"原始内容","originalSender":"张三"}` | +| `REVOKED` | 服务端下发,客户端只读 | + +## TypeScript 类型定义 + +```ts +interface ImMessage { + id: string + appId: string + fromUserId: string + toId: string + chatType: 'SINGLE' | 'GROUP' + msgType: MsgType + content: string + status: 'SENT' | 'REVOKED' + createdAt: string // ISO 8601 +} + +interface ImGroup { + id: string + appId: string + name: string + creatorId: string + memberIds: string[] + adminIds: string[] + createdAt: string +} +``` diff --git a/docs-site/docs/server/api.md b/docs-site/docs/server/api.md new file mode 100644 index 0000000..28881fa --- /dev/null +++ b/docs-site/docs/server/api.md @@ -0,0 +1,267 @@ +# Server API 参考 + +**Base URL**:`https://sentry.xuqinmin.com` + +所有 API 通过 Nginx 反代,无需区分内部端口。 + +## 认证 + +除 `/api/im/auth/login` 外,所有 IM 接口需在请求头携带 JWT Token: + +``` +Authorization: Bearer +``` + +Token 由 `/api/im/auth/login` 接口签发。 + +--- + +## IM 服务(/api/im/) + +### 登录 · 获取 Token + +``` +POST /api/im/auth/login +``` + +**Query 参数** + +| 参数 | 必填 | 说明 | +|------|------|------| +| `appId` | 是 | 应用 ID | +| `userId` | 是 | 用户 ID | +| `nickname` | 是 | 昵称 | + +**响应** + +```json +{ "token": "eyJ..." } +``` + +--- + +### WebSocket 连接 + +``` +WSS /ws/im?token=&appId= +``` + +- 协议:STOMP over WebSocket +- 单聊订阅:`/user/{userId}/queue/messages` +- 群聊订阅:`/topic/group/{groupId}` + +--- + +### 发送消息 + +``` +POST /api/im/messages +Authorization: Bearer +Content-Type: application/json +``` + +**请求体** + +```json +{ + "toId": "user_002", + "chatType": "SINGLE", + "msgType": "TEXT", + "content": "Hello!" +} +``` + +`chatType`:`SINGLE` | `GROUP` + +`msgType`:`TEXT` | `IMAGE` | `VIDEO` | `AUDIO` | `FILE` | `CUSTOM` | `LOCATION` | `NOTIFY` | `RICH_TEXT` | `CALL_AUDIO` | `CALL_VIDEO` | `FORWARD` + +**响应**:`ImMessage` 对象 + +--- + +### 撤回消息 + +``` +PUT /api/im/messages/{messageId}/revoke +Authorization: Bearer +``` + +**响应**:更新后的 `ImMessage`(`status: "REVOKED"`,`msgType: "REVOKED"`) + +--- + +### 消息历史(单聊) + +``` +GET /api/im/messages/history?appId=&userId=&toId=&page=0&size=50 +Authorization: Bearer +``` + +**响应**:分页 `ImMessage` 列表 + +--- + +### 创建群组 + +``` +POST /api/im/groups +Authorization: Bearer +Content-Type: application/json +``` + +```json +{ + "appId": "ak_demo_chat", + "name": "开发群", + "memberIds": ["user_001", "user_002"] +} +``` + +**响应**:`ImGroup` 对象 + +--- + +### 获取群列表 + +``` +GET /api/im/groups?appId=ak_demo_chat +Authorization: Bearer +``` + +--- + +### 添加群成员 + +``` +POST /api/im/groups/{groupId}/members +Authorization: Bearer +Content-Type: application/json + +{ "userId": "user_003" } +``` + +--- + +### 移除群成员 + +``` +DELETE /api/im/groups/{groupId}/members/{targetUserId} +Authorization: Bearer +``` + +--- + +## 版本管理服务(/api/v1/updates/ 和 /api/v1/rn/) + +### 检查 App 更新 + +``` +GET /api/v1/updates/check?appId=&platform=ANDROID&versionCode=1 +``` + +**响应** + +```json +{ + "hasUpdate": true, + "versionCode": 2, + "versionName": "1.0.1", + "forceUpdate": false, + "downloadUrl": "https://cdn.example.com/app.apk", + "appStoreUrl": null, + "releaseNotes": "修复若干问题" +} +``` + +--- + +### 检查 RN Bundle 热更新 + +``` +GET /api/v1/rn/check?appId=&moduleId=home&version=1.0.0&platform=ANDROID +``` + +**响应** + +```json +{ + "hasUpdate": true, + "version": "1.0.1", + "downloadUrl": "https://cdn.example.com/bundles/home_1.0.1.bundle", + "md5": "a1b2c3d4...", + "size": 204800 +} +``` + +--- + +### 下载 Bundle + +`downloadUrl` 返回的 URL 可直接 `GET` 下载,响应体为 bundle 二进制内容。 + +--- + +## 租户服务(/api/) + +### 创建应用(租户管理后台调用) + +``` +POST /api/apps +Authorization: Bearer +Content-Type: application/json + +{ "name": "我的 App", "platform": "ANDROID" } +``` + +--- + +## 数据模型 + +### ImMessage + +```json +{ + "id": "uuid", + "appId": "ak_demo_chat", + "fromUserId": "user_001", + "toId": "user_002", + "chatType": "SINGLE", + "msgType": "TEXT", + "content": "Hello!", + "status": "SENT", + "mentionedUserIds": [], + "createdAt": "2026-04-24T10:00:00" +} +``` + +### ImGroup + +```json +{ + "id": "group_uuid", + "appId": "ak_demo_chat", + "name": "开发群", + "creatorId": "user_001", + "memberIds": ["user_001", "user_002"], + "adminIds": ["user_001"], + "createdAt": "2026-04-24T10:00:00" +} +``` + +--- + +## 错误码 + +| HTTP 状态 | code | 说明 | +|-----------|------|------| +| 400 | 400 | 请求参数错误 | +| 401 | 401 | Token 无效或过期 | +| 403 | 403 | 无权限操作(如撤回他人消息)| +| 404 | 404 | 资源不存在 | +| 500 | 500 | 服务器内部错误 | + +错误响应格式: + +```json +{ "code": 403, "message": "只能撤回自己发送的消息" } +``` diff --git a/docs-site/docs/vue3/index.md b/docs-site/docs/vue3/index.md new file mode 100644 index 0000000..314a7ff --- /dev/null +++ b/docs-site/docs/vue3/index.md @@ -0,0 +1,149 @@ +# Vue3 SDK 概览 + +**包名**:`@xuqm/vue3-sdk` · **版本**:0.1.0 · **支持**:Vue 3.4+、Vite 5+ + +## 功能模块 + +| 导出 | 功能 | +|------|------| +| `useXuqm()` | 全局初始化 Composable | +| `useIm()` | IM 单聊/群聊响应式状态 | +| `useUpdate()` | 版本检查与热更新 | +| `XuqmProvider` | 可选根组件(自动初始化)| + +## 安装 + +```bash +npm install @xuqm/vue3-sdk +``` + +从私有 Nexus 安装时,在 `.npmrc` 中添加: + +``` +@xuqm:registry=https://nexus.xuqinmin.com/repository/npm-hosted/ +``` + +## 快速接入 + +### 1. 全局初始化(main.ts) + +```ts +import { createApp } from 'vue' +import { createXuqm } from '@xuqm/vue3-sdk' +import App from './App.vue' + +const app = createApp(App) + +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', + debug: import.meta.env.DEV, +})) + +app.mount('#app') +``` + +### 2. IM 登录与消息监听 + +```vue + + + +``` + +### 3. 发送消息 + +```ts +// 文本 +await sendMessage('user_002', 'SINGLE', 'TEXT', 'Hello!') + +// 图片 +await sendMessage('user_002', 'SINGLE', 'IMAGE', JSON.stringify({ + url: 'https://cdn.example.com/img.jpg', + width: 1200, height: 800, +})) +``` + +### 4. 撤回消息 + +```ts +const revoked = await revokeMessage(msg.id) +``` + +### 5. 群聊 + +```ts +const { createGroup, listGroups, subscribeGroup, groupMessages } = useIm() + +// 创建群 +const group = await createGroup('开发群', ['user_001', 'user_002']) + +// 订阅群消息 +subscribeGroup(group.id) + +// 发群消息 +await sendMessage(group.id, 'GROUP', 'TEXT', '大家好') +``` + +### 6. 检查 App/RN 更新 + +```ts +import { useUpdate } from '@xuqm/vue3-sdk' + +const { checkAppUpdate, checkRNUpdate } = useUpdate() + +const appInfo = await checkAppUpdate(1) // 当前 versionCode +const rnBundle = await checkRNUpdate('home', '1.0.0') +``` + +## 响应式状态 + +`useIm()` 返回的响应式 ref: + +```ts +const { + messages, // Ref 单聊消息列表 + groupMessages, // Ref 当前群消息列表 + connected, // Ref WS 连接状态 + currentUser, // Ref 当前登录用户 +} = useIm() +``` + +## 消息气泡组件(内置) + +SDK 内置基础气泡组件,开箱即用: + +```vue + + + +``` diff --git a/docs-site/package.json b/docs-site/package.json new file mode 100644 index 0000000..9252879 --- /dev/null +++ b/docs-site/package.json @@ -0,0 +1,13 @@ +{ + "name": "@xuqm/docs-site", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "vitepress dev docs", + "build": "vitepress build docs", + "preview": "vitepress preview docs" + }, + "devDependencies": { + "vitepress": "^1.5.0" + } +} diff --git a/nginx/default.conf b/nginx/default.conf index a4e3066..eff67e6 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -13,4 +13,9 @@ server { alias /usr/share/nginx/html/ops/; try_files $uri $uri/ /ops/index.html; } + + location /docs/ { + alias /usr/share/nginx/html/docs/; + try_files $uri $uri/ /docs/index.html; + } } diff --git a/package.json b/package.json index f4901bb..8ab0f69 100644 --- a/package.json +++ b/package.json @@ -4,11 +4,13 @@ "packageManager": "yarn@1.22.22", "workspaces": [ "tenant-platform", - "ops-platform" + "ops-platform", + "docs-site" ], "scripts": { "dev:tenant": "yarn workspace tenant-platform dev", "dev:ops": "yarn workspace ops-platform dev", + "dev:docs": "yarn workspace docs-site dev", "build": "yarn workspaces run build" } }