docs: add detailed documentation

这个提交包含在:
XuqmGroup 2026-04-21 22:25:34 +08:00
父节点 ad0a31bd91
当前提交 61ffd1bc8c
共有 3 个文件被更改,包括 616 次插入0 次删除

248
README.md 普通文件
查看文件

@ -0,0 +1,248 @@
# XuqmGroup React Native SDK 文档
> TypeScript · React Native 0.76+ · 发布至 Nexus npm
## 安装
```bash
# .npmrc 已配置私有 registry,直接安装
npm install @xuqm/rn-sdk
# 或
yarn add @xuqm/rn-sdk
# 依赖安装peerDependencies
npm install @react-native-async-storage/async-storage
```
## 目录结构
```
XuqmGroup-RNSDK/src/
├── core/
│ ├── http.ts # fetch HTTP 客户端,AsyncStorage Token
│ └── sdk.ts # XuqmSDK 初始化入口
├── im/
│ └── imClient.ts # WebSocket IM 客户端,指数退避重连
├── push/
│ └── pushSDK.ts # 推送 Token 注册
├── update/
│ └── updateSDK.ts # 检查更新 / 下载 Bundle
└── index.ts # 统一导出
```
---
## 快速开始
### 1. 初始化App 入口)
```typescript
import { XuqmSDK } from '@xuqm/rn-sdk'
await XuqmSDK.init({
appKey: 'ak_your_app_key',
appSecret: 'as_your_app_secret',
apiBaseUrl: 'https://api.xuqm.com',
imBaseUrl: 'wss://im.xuqm.com',
debug: __DEV__,
})
```
### 2. 用户登录后设置 Token
```typescript
await XuqmSDK.setToken('eyJ...')
// 登出时
await XuqmSDK.setToken(null)
```
Token 持久化存储于 `AsyncStorage`,App 重启后自动恢复。
---
## HTTP 客户端
```typescript
import { http } from '@xuqm/rn-sdk'
// 自动附加 Bearer Token
const data = await http.get<UserInfo>('/api/user/profile')
const result = await http.post<LoginResp>('/api/auth/login', { account, password })
```
---
## IM 模块
### ImClient
```typescript
import { ImClient, MsgType, ChatType } from '@xuqm/rn-sdk'
const im = new ImClient()
im.on('connected', () => console.log('IM 已连接'))
im.on('disconnected', (code, reason) => console.log('断开', code))
im.on('message', (msg) => {
console.log('新消息', msg.content)
// msg: ImMessage
})
im.on('revoke', ({ msgId, operatorId }) => {
console.log('消息被撤回', msgId)
})
im.on('error', (err) => console.error(err))
// 连接
im.connect()
// 发送消息
im.send({
toId: 'user_002',
chatType: ChatType.SINGLE,
msgType: MsgType.TEXT,
content: 'Hello from RN!',
})
// 撤回
im.revoke('msg-uuid')
// 组件卸载时断开
useEffect(() => {
im.connect()
return () => im.disconnect()
}, [])
```
### React Hook 封装示例
```typescript
import { useEffect, useState, useRef } from 'react'
import { ImClient, ImMessage } from '@xuqm/rn-sdk'
export function useIm() {
const [messages, setMessages] = useState<ImMessage[]>([])
const [connected, setConnected] = useState(false)
const imRef = useRef<ImClient | null>(null)
useEffect(() => {
const im = new ImClient()
imRef.current = im
im.on('connected', () => setConnected(true))
im.on('disconnected', () => setConnected(false))
im.on('message', (msg) => setMessages(prev => [...prev, msg]))
im.connect()
return () => im.disconnect()
}, [])
const send = (params: Parameters<ImClient['send']>[0]) =>
imRef.current?.send(params)
return { messages, connected, send }
}
```
### ImMessage 结构
```typescript
interface ImMessage {
id: string
fromId: string
toId: string
chatType: 'SINGLE' | 'GROUP'
msgType: MsgType
content: string
extra?: string
revoked: boolean
createdAt: string
}
```
### 消息类型MsgType
```typescript
enum MsgType {
TEXT = 'TEXT',
IMAGE = 'IMAGE',
VIDEO = 'VIDEO',
AUDIO = 'AUDIO',
FILE = 'FILE',
CUSTOM = 'CUSTOM',
LOCATION = 'LOCATION',
NOTIFY = 'NOTIFY',
RICH_TEXT = 'RICH_TEXT',
CALL_AUDIO = 'CALL_AUDIO',
CALL_VIDEO = 'CALL_VIDEO',
FORWARD = 'FORWARD',
}
```
### 自动重连
断线后指数退避重连3s → 6s → 12s → ... → 最大 30s。调用 `disconnect()` 后停止。
---
## 推送模块
```typescript
import { PushSDK } from '@xuqm/rn-sdk'
// 在获取到设备推送 Token 后调用(如小米、华为推送回调)
await PushSDK.registerToken({
appId: 'ak_xxx',
userId: 'user_001',
vendor: 'XIAOMI', // HUAWEI / XIAOMI / OPPO / VIVO / HONOR / APNS
token: 'device_push_token',
})
```
---
## 版本管理模块
### 检查 App 更新
```typescript
import { UpdateSDK } from '@xuqm/rn-sdk'
const result = await UpdateSDK.checkAppUpdate({
appId: 'ak_xxx',
platform: 'android', // 'android' | 'ios'
currentVersionCode: 10,
})
if (result.needsUpdate) {
console.log(result.versionName, result.downloadUrl, result.forceUpdate)
}
```
### 检查 RN Bundle 热更新
```typescript
const rnResult = await UpdateSDK.checkRnUpdate({
appId: 'ak_xxx',
moduleId: 'main',
platform: 'android',
currentVersion: '1.0.0',
})
if (rnResult.needsUpdate && rnResult.info) {
const { downloadUrl, md5 } = rnResult.info
// 下载 bundle,校验 md5,调用原生模块热加载
}
```
---
## 发版
```bash
# 确认 .npmrc 指向 https://nexus.xuqinmin.com/repository/npm-hosted/
# 登录 Nexus npm首次
npm login --registry=https://nexus.xuqinmin.com/repository/npm-hosted/
# 发版
npm publish
```
版本号在 `package.json``version` 字段维护。

279
docs/DEPLOY.md 普通文件
查看文件

@ -0,0 +1,279 @@
# 部署文档
## 一、基础设施要求
| 组件 | 版本 | 说明 |
|------|------|------|
| JDK | 21 | GraalVM 或 Eclipse Temurin |
| MySQL | 8.0+ | 4 个独立数据库 |
| Redis | 7.x | 验证码、会话标记 |
| Nginx | 1.24+ | 前端静态 + API 反代 |
| Maven | 3.9+ | 后端构建 |
| Node.js | 22+ | 前端构建 |
---
## 二、数据库初始化
服务启动时通过 `ddl-auto: update` 自动建表,只需提前创建数据库:
```sql
CREATE DATABASE xuqm_tenant CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE xuqm_im CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE xuqm_push CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE xuqm_update CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
---
## 三、后端构建与启动
### 构建
```bash
cd XuqmGroup-Server
mvn clean package -DskipTests
```
各模块 jar 生成于 `{module}/target/{module}-0.1.0-SNAPSHOT.jar`
### 环境变量
**tenant-service**:8081
```bash
export SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/xuqm_tenant?...
export SPRING_DATASOURCE_USERNAME=xuqm
export SPRING_DATASOURCE_PASSWORD=your_db_password
export SPRING_DATA_REDIS_HOST=redis
export SPRING_MAIL_USERNAME=noreply@xuqm.com
export SPRING_MAIL_PASSWORD=your_smtp_password
export JWT_SECRET=your_256bit_secret
export OPS_ADMIN_USERNAME=admin
export OPS_ADMIN_PASSWORD=your_ops_password
```
**im-service**:8082
```bash
export SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/xuqm_im?...
export SPRING_DATASOURCE_USERNAME=xuqm
export SPRING_DATASOURCE_PASSWORD=your_db_password
export SPRING_DATA_REDIS_HOST=redis
export JWT_SECRET=your_256bit_secret_im
```
**push-service**:8083
```bash
export SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/xuqm_push?...
export SPRING_DATASOURCE_USERNAME=xuqm
export SPRING_DATASOURCE_PASSWORD=your_db_password
export JWT_SECRET=your_256bit_secret_push
# 华为推送
export HUAWEI_APP_ID=your_huawei_app_id
export HUAWEI_APP_SECRET=your_huawei_secret
# 小米推送
export XIAOMI_APP_SECRET=your_xiaomi_secret
# iOS APNs
export APNS_KEY_ID=your_key_id
export APNS_TEAM_ID=your_team_id
export APNS_KEY_PATH=/opt/xuqm/apns_key.p8
export APNS_BUNDLE_ID=com.yourcompany.app
```
**update-service**:8084
```bash
export SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/xuqm_update?...
export SPRING_DATASOURCE_USERNAME=xuqm
export SPRING_DATASOURCE_PASSWORD=your_db_password
export JWT_SECRET=your_256bit_secret_update
export UPDATE_UPLOAD_DIR=/data/xuqm/update
export UPDATE_BASE_URL=https://update.xuqm.com
```
### 启动
```bash
java -jar tenant-service/target/tenant-service-*.jar &
java -jar im-service/target/im-service-*.jar &
java -jar push-service/target/push-service-*.jar &
java -jar update-service/target/update-service-*.jar &
```
---
## 四、前端构建与部署
```bash
cd XuqmGroup-Web
yarn install
yarn workspace tenant-platform build # dist/ → /var/www/tenant
yarn workspace ops-platform build # dist/ → /var/www/ops
```
### Nginx 配置
```nginx
# 租户开放平台
server {
listen 80;
server_name tenant.xuqm.com;
root /var/www/tenant;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8081/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# 运营管理平台
server {
listen 80;
server_name ops.xuqm.com;
root /var/www/ops;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:8081/api/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# IM WebSocket 反代
server {
listen 80;
server_name im.xuqm.com;
location /ws/im {
proxy_pass http://127.0.0.1:8082;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 86400;
}
location /api/im/ {
proxy_pass http://127.0.0.1:8082/api/im/;
}
}
# 版本管理文件服务
server {
listen 80;
server_name update.xuqm.com;
location / {
proxy_pass http://127.0.0.1:8084/;
}
}
```
---
## 五、Docker Compose可选
```yaml
version: '3.9'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: xuqm
MYSQL_PASSWORD: xuqm_password
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
tenant-service:
image: eclipse-temurin:21-jre
volumes:
- ./XuqmGroup-Server/tenant-service/target:/app
command: java -jar /app/tenant-service-0.1.0-SNAPSHOT.jar
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/xuqm_tenant?...
SPRING_DATA_REDIS_HOST: redis
ports:
- "8081:8081"
depends_on: [mysql, redis]
im-service:
image: eclipse-temurin:21-jre
volumes:
- ./XuqmGroup-Server/im-service/target:/app
command: java -jar /app/im-service-0.1.0-SNAPSHOT.jar
ports:
- "8082:8082"
depends_on: [mysql, redis]
push-service:
image: eclipse-temurin:21-jre
volumes:
- ./XuqmGroup-Server/push-service/target:/app
command: java -jar /app/push-service-0.1.0-SNAPSHOT.jar
ports:
- "8083:8083"
depends_on: [mysql]
update-service:
image: eclipse-temurin:21-jre
volumes:
- ./XuqmGroup-Server/update-service/target:/app
- update_files:/data/xuqm/update
command: java -jar /app/update-service-0.1.0-SNAPSHOT.jar
environment:
UPDATE_UPLOAD_DIR: /data/xuqm/update
ports:
- "8084:8084"
depends_on: [mysql]
volumes:
mysql_data:
update_files:
```
---
## 六、发版流程汇总
| 平台 | 步骤 |
|------|------|
| **后端** | `mvn clean package` → 替换 jar → 重启服务 |
| **前端** | `yarn build` → 替换 `dist/` → Nginx 无需重启 |
| **Android SDK** | 修改版本号 → `./gradlew publish` → Nexus |
| **iOS SDK (SPM)** | 修改版本号 → `git tag x.y.z && git push origin x.y.z` |
| **iOS SDK (CocoaPods)** | `pod repo push xuqm-specs XuqmSDK.podspec` |
| **RN SDK** | 修改 `package.json` version → `npm publish` |
| **Vue3 SDK** | 修改 `package.json` version → `npm run build && npm publish` |
| **HarmonyOS SDK** | 修改 `oh-package.json5` version → `ohpm publish` |
---
## 七、健康检查
各服务均暴露 Spring Actuator 端点:
```bash
curl http://localhost:8081/actuator/health
curl http://localhost:8082/actuator/health
curl http://localhost:8083/actuator/health
curl http://localhost:8084/actuator/health
```
正常返回:`{"status":"UP"}`

89
docs/PLATFORM_OVERVIEW.md 普通文件
查看文件

@ -0,0 +1,89 @@
# XuqmGroup 平台文档总览
> 版本0.1.0 | 最后更新2026-04-21
## 仓库索引
| 仓库 | 语言/框架 | Gogs 地址 | 说明 |
|------|-----------|-----------|------|
| [XuqmGroup-Server](./server/README.md) | Java 21 / Spring Boot 3.4 | https://xuqinmin.com/xuqinmin12/XuqmGroup-Server | 后端多模块服务 |
| [XuqmGroup-Web](./web/README.md) | Vue 3.5 / TypeScript | https://xuqinmin.com/xuqinmin12/XuqmGroup-Web | 租户平台 + 运营平台前端 |
| [XuqmGroup-AndroidSDK](./android-sdk/README.md) | Kotlin 2.3 / AGP 9.1 | https://xuqinmin.com/xuqinmin12/XuqmGroup-AndroidSDK | Android SDK |
| [XuqmGroup-iOSSDK](./ios-sdk/README.md) | Swift 5.9 / iOS 16+ | https://xuqinmin.com/xuqinmin12/XuqmGroup-iOSSDK | iOS SDK |
| [XuqmGroup-RNSDK](./rn-sdk/README.md) | TypeScript / RN 0.76+ | https://xuqinmin.com/xuqinmin12/XuqmGroup-RNSDK | React Native SDK |
| [XuqmGroup-Vue3SDK](./vue3-sdk/README.md) | TypeScript / Vue 3.5 | https://xuqinmin.com/xuqinmin12/XuqmGroup-Vue3SDK | Vue3 Web SDK |
| [XuqmGroup-HarmonySDK](./harmony-sdk/README.md) | ArkTS / HarmonyOS 5 | https://xuqinmin.com/xuqinmin12/XuqmGroup-HarmonySDK | 鸿蒙 SDK |
## 整体架构
```
┌─────────────────────────────────────────────────────────────┐
│ 客户端层 │
│ Android SDK iOS SDK RN SDK Vue3 SDK HarmonyOS SDK │
└───────────────────────────┬─────────────────────────────────┘
│ HTTPS / WSS
┌───────────────────────────▼─────────────────────────────────┐
│ 服务端层 │
│ ┌────────────┐ ┌──────────┐ ┌───────────┐ ┌────────────┐ │
│ │tenant-svc │ │im-service│ │push-svc │ │update-svc │ │
│ │ :8081 │ │ :8082 │ │ :8083 │ │ :8084 │ │
│ └─────┬──────┘ └────┬─────┘ └─────┬─────┘ └──────┬─────┘ │
│ └─────────────┴─────────────┴───────────────┘ │
│ ↓ JPA / JDBC │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ MySQL 8 (xuqm_tenant / xuqm_im / xuqm_push / │ │
│ │ xuqm_update) + Redis 7 │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 前端层 │
│ 租户开放平台 :5173 运营管理平台 :5174 │
└─────────────────────────────────────────────────────────────┘
```
## 核心概念
| 概念 | 说明 |
|------|------|
| **租户 (Tenant)** | 在开放平台注册的主账号,可创建子账号 |
| **应用 (App)** | 租户创建的业务应用,具有唯一 appKey/appSecret |
| **功能服务 (FeatureService)** | 挂载在 App 下的服务实例IM / 推送 / 版本管理,按平台Android / iOS / HarmonyOS独立开启 |
| **IM 账号** | 业务方通过 appKey 在 IM 服务创建的用户,仅存 userId,不存昵称/头像 |
| **运营平台** | 内部管理后台,独立账号体系,不与租户共用 |
## 统一响应格式
所有 HTTP 接口均返回:
```json
{
"code": 200,
"status": "0",
"data": { ... },
"message": "success"
}
```
| 字段 | 含义 |
|------|------|
| `code` | HTTP 语义码,200 成功,4xx/5xx 失败 |
| `status` | `"0"` 成功,`"1"` 业务失败 |
| `data` | 业务数据,失败时为 null |
| `message` | 错误描述 |
## 认证方式
- **租户平台**`Authorization: Bearer <tenant_jwt>`,由 `POST /api/auth/login` 颁发
- **IM 服务**`Authorization: Bearer <im_jwt>`,由 `POST /api/im/auth/login` 颁发;WebSocket 连接时通过 URL 参数 `?token=<im_jwt>` 传递
- **运营平台**`Authorization: Bearer <ops_jwt>`,由 `POST /api/auth/ops/login` 颁发
## 发版信息
| 平台 | Registry | 命令 |
|------|----------|------|
| npm (RN SDK / Vue3 SDK) | https://nexus.xuqinmin.com/repository/npm-hosted/ | `npm publish` |
| Android Maven | https://nexus.xuqinmin.com/repository/android-hosted/ | `./gradlew publish` |
| iOS SPM | Git Tag | `git tag x.y.z && git push origin x.y.z` |
| iOS CocoaPods | https://xuqinmin.com/xuqinmin12/xuqm-specs | `pod repo push xuqm-specs XuqmSDK.podspec` |
| HarmonyOS | ohpm (OpenHarmony Package Manager) | `ohpm publish` |