diff --git a/README.md b/README.md new file mode 100644 index 0000000..3589ab9 --- /dev/null +++ b/README.md @@ -0,0 +1,498 @@ +# XuqmGroup-Server 后端文档 + +> Spring Boot 3.4.4 · Java 21 · Maven 多模块 + +## 模块结构 + +``` +XuqmGroup-Server/ +├── pom.xml # 父 POM,统一依赖版本 +├── common/ # 公共库(ApiResponse、JWT、异常处理) +├── tenant-service/ # 租户服务 :8081 +├── im-service/ # IM 服务 :8082 +├── push-service/ # 推送服务 :8083 +└── update-service/ # 版本管理服务 :8084 +``` + +## 技术栈 + +| 组件 | 版本 | +|------|------| +| Spring Boot | 3.4.4 | +| Java | 21 | +| Spring Security 6 | JWT 无状态认证 | +| Spring Data JPA | Hibernate 6,ddl-auto: update | +| MySQL | 8.x | +| Redis | 7.x(验证码、子账号会话) | +| JJWT | 0.12.6,HMAC-SHA256 | +| Spring Mail | 邮件验证码 | +| Spring WebSocket + STOMP | IM 实时通信 | + +## 快速启动 + +```bash +# 前置:MySQL 8 + Redis 7 本地运行 +cd XuqmGroup-Server + +# 启动所有服务(各模块独立启动) +cd tenant-service && mvn spring-boot:run & +cd im-service && mvn spring-boot:run & +cd push-service && mvn spring-boot:run & +cd update-service && mvn spring-boot:run & +``` + +首次启动会自动建表(ddl-auto: update)。 +运营平台默认管理员:`admin` / `Admin@123456`(可通过 `ops.admin.*` 配置覆盖)。 + +--- + +## tenant-service(租户服务)`:8081` + +### 数据库表 + +| 表名 | 说明 | +|------|------| +| `t_tenant` | 租户主账号 & 子账号 | +| `t_app` | 应用 | +| `t_feature_service` | 功能服务(IM/推送/版本管理) | +| `t_email_verification` | 邮箱验证码 | +| `t_ops_admin` | 运营平台管理员 | + +### 接口列表 + +#### 认证(无需 Token) + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/auth/captcha` | 获取图形验证码 | +| POST | `/api/auth/send-email-code?email=&purpose=` | 发送邮箱验证码(purpose: REGISTER / FORGOT_PASSWORD / SUB_ACCOUNT) | +| POST | `/api/auth/register` | 注册主账号 | +| POST | `/api/auth/login` | 登录,返回 JWT | +| POST | `/api/auth/forgot-password?email=` | 发送重置密码邮件 | +| POST | `/api/auth/reset-password?email=&code=&newPassword=` | 重置密码 | + +**注册请求体** +```json +{ + "username": "demo", + "password": "Demo@123456", + "email": "demo@example.com", + "nickname": "Demo", + "emailCode": "AB3K" +} +``` + +**登录请求体** +```json +{ + "account": "demo", + "password": "Demo@123456", + "captchaKey": "uuid-from-captcha-api", + "captchaCode": "XK2P" +} +``` + +**登录响应** +```json +{ + "code": 200, "status": "0", + "data": { "token": "eyJ..." }, + "message": "success" +} +``` + +#### 应用管理(需 Token) + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/apps` | 查询当前租户的应用列表 | +| GET | `/api/apps/{id}` | 查询应用详情 | +| POST | `/api/apps` | 创建应用 | +| PUT | `/api/apps/{id}` | 更新应用信息 | +| DELETE | `/api/apps/{id}` | 删除应用 | + +**创建应用请求体** +```json +{ + "name": "我的App", + "packageName": "com.example.myapp", + "description": "描述", + "iconUrl": "https://cdn.example.com/icon.png" +} +``` + +**应用对象(响应)** +```json +{ + "id": "uuid", + "tenantId": "uuid", + "name": "我的App", + "packageName": "com.example.myapp", + "appKey": "ak_xxxxxxxx", + "appSecret": "as_xxxxxxxx", + "createdAt": "2026-04-21T00:00:00" +} +``` + +#### 功能服务(需 Token) + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/apps/{appId}/services` | 获取应用下所有功能服务 | +| POST | `/api/apps/{appId}/services/toggle?platform=&serviceType=&enable=` | 开启/关闭功能服务 | +| POST | `/api/apps/{appId}/services/{id}/regenerate-key` | 重新生成 secretKey | + +**platform 枚举**:`ANDROID` / `IOS` / `HARMONY` +**serviceType 枚举**:`IM` / `PUSH` / `UPDATE` + +#### 子账号(需 Token) + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/sub-accounts` | 查询子账号列表 | +| POST | `/api/sub-accounts/send-verify-code?email=` | 发送邮箱验证码(24h 内有效一次) | +| POST | `/api/sub-accounts/verify-email?email=&code=` | 验证邮箱(通过后 24h 内可创建) | +| POST | `/api/sub-accounts` | 创建子账号(需先验证邮箱) | +| DELETE | `/api/sub-accounts/{id}` | 禁用子账号 | +| GET | `/api/sub-accounts/generate-password` | 生成随机密码 | + +**创建子账号请求体** +```json +{ + "username": "sub_user", + "password": "Sub@123456", + "email": "sub@example.com", + "nickname": "子账号" +} +``` + +#### 运营平台(需 OPS Token) + +| 方法 | 路径 | 说明 | +|------|------|------| +| POST | `/api/auth/ops/login` | 运营平台登录 | +| GET | `/api/ops/tenants?keyword=&page=&size=` | 分页查询租户 | +| POST | `/api/ops/tenants/{id}/toggle-status` | 启用/禁用租户 | +| GET | `/api/ops/statistics` | 获取统计数据 | + +**运营登录请求体** +```json +{ "username": "admin", "password": "Admin@123456" } +``` + +**统计响应** +```json +{ + "data": { + "totalTenants": 128, + "todayNew": 5, + "activeApps": 42, + "onlineUsers": 0 + } +} +``` + +--- + +## im-service(IM 服务)`:8082` + +### 数据库表 + +| 表名 | 说明 | +|------|------| +| `im_account` | IM 用户账号(仅存 userId,不含昵称/头像) | +| `im_group` | 群组(memberIds、adminIds 为逗号分隔字符串) | +| `im_message` | 消息记录 | +| `im_keyword_filter` | 关键词过滤规则 | +| `im_webhook_config` | Webhook 配置 | + +### IM 账号登录 + +``` +POST /api/im/auth/login + ?appId=ak_xxx + &userId=user_001 + &nickname=张三 (可选,仅首次注册时存入外部系统) + &avatar=https://... (可选) +``` + +响应:`{ "data": { "token": "eyJ..." } }` + +### HTTP 消息接口 + +| 方法 | 路径 | 说明 | +|------|------|------| +| POST | `/api/im/messages/send?appId=` | 发送消息 | +| POST | `/api/im/messages/{id}/revoke?appId=` | 撤回消息 | +| GET | `/api/im/messages/history/{toId}?appId=&page=&size=` | 查询历史消息 | + +**发送消息请求体** +```json +{ + "toId": "user_002", + "chatType": "SINGLE", + "msgType": "TEXT", + "content": "Hello!", + "mentionedUserIds": "" +} +``` + +**消息类型(MsgType)** + +| 值 | 说明 | +|----|------| +| TEXT | 文本(支持表情 Unicode / 自定义表情 ID) | +| IMAGE | 图片(content 为 URL) | +| VIDEO | 视频 | +| AUDIO | 语音 | +| FILE | 文件 | +| CUSTOM | 自定义(content 为 JSON 字符串) | +| LOCATION | 位置(content 为 `{"lat":x,"lng":y,"address":"..."}`) | +| NOTIFY | 系统通知 | +| RICH_TEXT | 图文混排 | +| CALL_AUDIO | 音频通话信令 | +| CALL_VIDEO | 视频通话信令 | +| FORWARD | 转发(content 为原消息 JSON) | +| REVOKED | 已撤回(系统占位,不可主动发送) | + +### WebSocket 实时通信 + +**连接** +``` +ws://localhost:8082/ws/im?token= +``` +支持 STOMP 协议(可直接使用原生 WebSocket 发 JSON frame)。 + +**发送消息(客户端 → 服务端)** +```json +{ + "destination": "/app/chat.send", + "payload": { + "appId": "ak_xxx", + "toId": "user_002", + "chatType": "SINGLE", + "msgType": "TEXT", + "content": "Hello!" + } +} +``` + +**接收消息(服务端 → 客户端)** +- 单聊推送至:`/user/{userId}/queue/messages` +- 群聊推送至:`/topic/group/{groupId}` + +Frame 格式: +```json +{ + "type": "MESSAGE", + "payload": { + "id": "uuid", + "fromId": "user_001", + "toId": "user_002", + "chatType": "SINGLE", + "msgType": "TEXT", + "content": "Hello!", + "revoked": false, + "createdAt": "2026-04-21T10:00:00" + } +} +``` + +**撤回消息(客户端 → 服务端)** +```json +{ + "destination": "/app/chat.revoke", + "payload": { "appId": "ak_xxx", "messageId": "msg-uuid" } +} +``` + +**撤回推送(服务端 → 客户端)** +```json +{ + "type": "REVOKE", + "payload": { "msgId": "msg-uuid", "operatorId": "user_001" } +} +``` + +### 关键词过滤 + +在 `im_keyword_filter` 表中配置,支持 `REPLACE`(替换为 `*`)和 `BLOCK`(拒绝发送)两种动作,pattern 为正则表达式。 + +### Webhook + +在 `im_webhook_config` 表中为 App 配置 URL,消息发送后异步 HTTP POST 通知,超时 3000ms,格式: +```json +{ + "event": "message", + "appId": "ak_xxx", + "message": { ...消息对象... } +} +``` + +--- + +## push-service(推送服务)`:8083` + +### 数据库表 + +| 表名 | 说明 | +|------|------| +| `push_device_token` | 设备推送 token(appId + userId + vendor 唯一) | + +### 支持厂商 + +`HUAWEI` / `XIAOMI` / `OPPO` / `VIVO` / `HONOR` / `APNS`(iOS)/ `FCM` + +### 接口 + +| 方法 | 路径 | 说明 | +|------|------|------| +| POST | `/api/push/register` | 注册设备 token | +| POST | `/api/push/send` | 向指定用户推送通知 | + +**注册 token** +``` +POST /api/push/register + ?appId=ak_xxx + &userId=user_001 + &vendor=HUAWEI + &token=device_push_token +``` + +**发送推送** +``` +POST /api/push/send + ?appId=ak_xxx + &userId=user_001 + &title=新消息 + &body=张三: Hello! + &payload={"type":"IM","msgId":"uuid"} +``` + +### 环境变量配置 + +```yaml +push: + huawei: + app-id: ${HUAWEI_APP_ID} + app-secret: ${HUAWEI_APP_SECRET} + xiaomi: + app-secret: ${XIAOMI_APP_SECRET} + apns: + key-id: ${APNS_KEY_ID} + team-id: ${APNS_TEAM_ID} + key-path: ${APNS_KEY_PATH} # .p8 文件路径 + bundle-id: ${APNS_BUNDLE_ID} + production: false # true = 生产环境 +``` + +--- + +## update-service(版本管理服务)`:8084` + +### 数据库表 + +| 表名 | 说明 | +|------|------| +| `app_version` | 原生 App 版本(Android APK / iOS 跳转链接) | +| `rn_bundle` | RN Bundle 版本 | + +### App 版本管理 + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/v1/updates/app/check` | 检查更新 | +| POST | `/api/v1/updates/app/upload` | 上传版本(APK 文件 multipart) | +| POST | `/api/v1/updates/app/{id}/publish` | 发布版本 | +| GET | `/api/v1/updates/app/list` | 版本列表 | + +**检查更新** +``` +GET /api/v1/updates/app/check + ?appId=ak_xxx + &platform=ANDROID + ¤tVersionCode=10 +``` + +响应(有更新): +```json +{ + "data": { + "needsUpdate": true, + "versionName": "1.1.0", + "versionCode": 11, + "downloadUrl": "http://update.xuqm.com/files/apk/xxx.apk", + "changeLog": "修复若干问题", + "forceUpdate": false, + "appStoreUrl": "", + "marketUrl": "" + } +} +``` + +**platform 枚举**:`ANDROID` / `IOS` / `HARMONY` + +**上传 APK(multipart/form-data)** +``` +POST /api/v1/updates/app/upload + appId=ak_xxx + platform=ANDROID + versionName=1.1.0 + versionCode=11 + changeLog=更新内容 + forceUpdate=false + apkFile= +``` + +### RN Bundle 管理 + +| 方法 | 路径 | 说明 | +|------|------|------| +| GET | `/api/v1/rn/update/check` | 检查 RN Bundle 更新 | +| POST | `/api/v1/rn/upload` | 上传 Bundle 文件 | +| POST | `/api/v1/rn/{id}/publish` | 发布 Bundle | + +**检查 RN 更新** +``` +GET /api/v1/rn/update/check + ?appId=ak_xxx + &moduleId=main + &platform=android + ¤tVersion=1.0.0 +``` + +响应(有更新): +```json +{ + "data": { + "needsUpdate": true, + "latestVersion": "1.1.0", + "downloadUrl": "http://...", + "md5": "abc123...", + "minCommonVersion": "1.0.0", + "note": "热更新说明" + } +} +``` + +**上传 Bundle(multipart/form-data)** +``` +POST /api/v1/rn/upload + appId=ak_xxx + moduleId=main + platform=ANDROID + version=1.1.0 + minCommonVersion=1.0.0 + note=修复闪退 + bundle= +``` + +服务端自动计算 MD5,存储至 `{upload-dir}/rn/{appId}/{platform}/{moduleId}/`。 + +### 环境变量配置 + +```yaml +update: + upload-dir: ${UPDATE_UPLOAD_DIR:/tmp/xuqm-update} + base-url: ${UPDATE_BASE_URL:http://localhost:8084} +``` 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` |