From 2c7ca601ffb3e0f03daca9061b143bef4d0fa563 Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Tue, 21 Apr 2026 22:25:33 +0800 Subject: [PATCH] docs: add detailed documentation --- README.md | 270 ++++++++++++++++++++++++++++++++++++ docs/DEPLOY.md | 279 ++++++++++++++++++++++++++++++++++++++ docs/PLATFORM_OVERVIEW.md | 89 ++++++++++++ 3 files changed, 638 insertions(+) create mode 100644 README.md create mode 100644 docs/DEPLOY.md create mode 100644 docs/PLATFORM_OVERVIEW.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..aa504fc --- /dev/null +++ b/README.md @@ -0,0 +1,270 @@ +# XuqmGroup iOS SDK 文档 + +> Swift 5.9 · iOS 16+ · macOS 13+ · async/await + +## 模块结构 + +``` +XuqmGroup-iOSSDK/ +├── Package.swift # SPM 包定义 +├── XuqmSDK.podspec # CocoaPods 发版描述 +├── PUBLISH.md # 发版操作手册 +└── Sources/XuqmSDK/ + ├── Core/ + │ ├── XuqmSDK.swift # 入口:init / setToken + │ ├── SDKConfig.swift # 配置结构体 + │ ├── ApiClient.swift # HTTP 客户端(URLSession) + │ └── TokenStore.swift # Keychain Token 存储 + ├── IM/ + │ └── ImClient.swift # WebSocket IM 客户端 + ├── Push/ + │ └── PushSDK.swift # APNs Token 注册 + └── Update/ + └── UpdateSDK.swift # 版本检查 / Bundle 下载 +``` + +## 集成 + +### Swift Package Manager(推荐) + +在 Xcode → File → Add Package Dependencies,输入仓库地址: +``` +https://xuqinmin.com/xuqinmin12/XuqmGroup-iOSSDK.git +``` +选择版本规则 `Up to Next Major: 0.1.0`。 + +或在 `Package.swift` 中添加: +```swift +dependencies: [ + .package(url: "https://xuqinmin.com/xuqinmin12/XuqmGroup-iOSSDK.git", from: "0.1.0") +], +targets: [ + .target(name: "YourApp", dependencies: ["XuqmSDK"]) +] +``` + +### CocoaPods + +```ruby +# Podfile +source 'https://xuqinmin.com/xuqinmin12/xuqm-specs.git' +source 'https://cdn.cocoapods.org/' + +pod 'XuqmSDK', '~> 0.1.0' +``` + +--- + +## 快速开始 + +### 1. 初始化(AppDelegate / @main) + +```swift +import XuqmSDK + +@main +struct MyApp: App { + init() { + XuqmSDK.initialize( + appKey: "ak_your_app_key", + appSecret: "as_your_app_secret", + apiBaseUrl: "https://api.xuqm.com", + imBaseUrl: "wss://im.xuqm.com", + debug: true + ) + } +} +``` + +### 2. 登录后存储 Token + +```swift +// 调用你的业务登录接口获得 token +await XuqmSDK.setToken(token) +``` + +--- + +## Core + +### ApiClient + +基于 `URLSession`,async/await,自动附加 Bearer Token,统一解析 `ApiResponse`。 + +```swift +// 定义响应模型 +struct LoginResponse: Decodable { + let token: String +} + +// 发起请求 +let response: LoginResponse = try await ApiClient.post( + path: "/api/im/auth/login", + body: ["appId": appId, "userId": userId] +) +``` + +### TokenStore + +基于 `Keychain` 存储(`kSecClassGenericPassword`),App 重启后自动恢复。 + +```swift +await XuqmSDK.setToken("eyJ...") // 存储 +let token = XuqmSDK.getToken() // 读取(同步) +await XuqmSDK.setToken(nil) // 清除(登出) +``` + +--- + +## IM + +### ImClient + +```swift +import XuqmSDK + +class ChatViewController: UIViewController, ImEventDelegate { + + let imClient = ImClient() + + override func viewDidLoad() { + super.viewDidLoad() + imClient.delegate = self + imClient.connect() + } + + // 发送消息 + func sendMessage() throws { + try imClient.send(SendMessageParams( + toId: "user_002", + chatType: .single, + msgType: .text, + content: "Hello!" + )) + } + + // 撤回消息 + func revokeMessage(msgId: String) throws { + try imClient.revoke(msgId: msgId) + } + + deinit { imClient.disconnect() } +} + +// MARK: - ImEventDelegate +extension ChatViewController { + func onConnected() { print("IM 连接成功") } + func onDisconnected(code: Int, reason: String) { print("断开: \(code)") } + func onMessage(_ msg: ImMessage) { /* 更新 UI */ } + func onRevoke(msgId: String, operatorId: String) { /* 标记消息已撤回 */ } + func onError(_ error: Error) { print("错误: \(error)") } +} +``` + +### ImMessage 结构 + +```swift +public struct ImMessage: Decodable { + public let id: String + public let fromId: String + public let toId: String + public let chatType: ChatType // single / group + public let msgType: MsgType + public let content: String + public let extra: String? + public let revoked: Bool + public let createdAt: String +} +``` + +### 消息类型(MsgType) + +`text` / `image` / `video` / `audio` / `file` / `custom` / `location` / `notify` / `richText` / `callAudio` / `callVideo` / `forward` + +### 自动重连 + +断线后指数退避重连,初始 3s,最大 30s。`disconnect()` 后停止。 + +--- + +## Push + +```swift +import XuqmSDK + +// 在 didRegisterForRemoteNotificationsWithDeviceToken 中调用 +func application(_ application: UIApplication, + didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { + Task { + try await PushSDK.registerToken( + appId: "ak_xxx", + userId: "user_001", + token: deviceToken + ) + } +} +``` + +`PushSDK.registerToken` 内部将 `Data` 转换为十六进制字符串,vendor 固定为 `APNS`。 + +--- + +## Update + +### 检查原生版本更新 + +```swift +import XuqmSDK + +let result = try await UpdateSDK.checkAppUpdate(appId: "ak_xxx") +if result.needsUpdate, let info = result.info { + print("最新版本: \(info.versionName)") + // iOS 只能跳转 App Store + if let url = URL(string: info.appStoreUrl) { + await UIApplication.shared.open(url) + } +} +``` + +### 检查 RN Bundle 更新 + +```swift +let rnResult = try await UpdateSDK.checkRnUpdate( + appId: "ak_xxx", + moduleId: "main", + currentVersion: "1.0.0" +) + +if rnResult.needsUpdate, let info = rnResult.info { + let filePath = try await UpdateSDK.downloadBundle( + from: info.downloadUrl, + filename: "main.ios.bundle" + ) + // 校验 MD5,通知 RN 引擎加载 +} +``` + +--- + +## 发版 + +### SPM(推荐) + +```bash +git add -A && git commit -m "release: 0.1.0" +git tag 0.1.0 +git push origin main 0.1.0 +``` + +Xcode 用户在 Package Dependencies 刷新即可获取新版本。 + +### CocoaPods 私有 Spec + +```bash +# 首次(只需一次) +pod repo add xuqm-specs https://xuqinmin.com/xuqinmin12/xuqm-specs.git + +# 每次发版 +pod spec lint XuqmSDK.podspec --allow-warnings +pod repo push xuqm-specs XuqmSDK.podspec --allow-warnings +``` diff --git a/docs/DEPLOY.md b/docs/DEPLOY.md new file mode 100644 index 0000000..245327e --- /dev/null +++ b/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"}` diff --git a/docs/PLATFORM_OVERVIEW.md b/docs/PLATFORM_OVERVIEW.md new file mode 100644 index 0000000..6cda91b --- /dev/null +++ b/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 `,由 `POST /api/auth/login` 颁发 +- **IM 服务**:`Authorization: Bearer `,由 `POST /api/im/auth/login` 颁发;WebSocket 连接时通过 URL 参数 `?token=` 传递 +- **运营平台**:`Authorization: Bearer `,由 `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` |