docs(deploy): 移除 Jenkins 配置和 Android Demo 计划文档
- 删除 jenkins-setup.md 完整的 Jenkins 服务配置指南 - 更新 README.md 部署文档标题为公有化部署文档 - 添加私有化部署说明章节和相关设计文档链接 - 从 REST API 设计文档中移除 demo-service 相关描述 - 更新推送架构图中业务服务端描述为客户端服务器 - 删除 android-demo-plan.md Android Demo 开发计划文档 - 删除 multi-platform-im-roadmap.md 多平台 IM 路线图文档 - 删除 java-im-server-sdk-plan.md Java IM 服务端 SDK 计划文档
这个提交包含在:
父节点
df7557b77f
当前提交
7ef2d011a3
@ -1,218 +0,0 @@
|
|||||||
# XuqmGroup Vue3 SDK 测试报告
|
|
||||||
|
|
||||||
> **生成时间**: 2026-04-30
|
|
||||||
> **测试环境**: Node.js v22.22.2, macOS
|
|
||||||
> **服务端**: 192.168.113.37 (本地 IntelliJ 启动)
|
|
||||||
> **参考文档**: `/Users/xuqinmin/Projects/XuqmGroup/ANDROID_SDK_DEBUG.md`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 一、测试概览
|
|
||||||
|
|
||||||
| 类别 | 数量 | 通过 | 失败 |
|
|
||||||
|------|------|------|------|
|
|
||||||
| 单元测试 | 39 | 39 | 0 |
|
|
||||||
| 集成测试 (E2E) | 36 | 36 | 0 |
|
|
||||||
| **总计** | **75** | **75** | **0** |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 二、发现的 Bug 及修复
|
|
||||||
|
|
||||||
### 🔴 Bug 1: ImClient 未实现 STOMP 协议
|
|
||||||
|
|
||||||
**现象**: WebSocket 连接成功,但发送消息后服务端不处理,history 中无记录,无实时推送。
|
|
||||||
**根因**: Vue3 SDK 的 `ImClient.ts` 发送的是自定义 JSON 格式:
|
|
||||||
```json
|
|
||||||
{"destination": "/app/chat.send", "payload": {...}}
|
|
||||||
```
|
|
||||||
而服务端 Spring STOMP 期望标准 STOMP 协议帧:
|
|
||||||
```
|
|
||||||
SEND\ndestination:/app/chat.send\ncontent-type:application/json\n\n{body}\x00
|
|
||||||
```
|
|
||||||
**修复**: 重写 `ImClient.ts`,完整实现 STOMP 协议:
|
|
||||||
- CONNECT / CONNECTED 握手
|
|
||||||
- SEND 帧发送消息
|
|
||||||
- SUBSCRIBE 自动订阅 `/user/queue/messages`
|
|
||||||
- MESSAGE / ERROR 帧解析
|
|
||||||
- DISCONNECT 优雅关闭
|
|
||||||
|
|
||||||
**状态**: ✅ 已修复并验证
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🔴 Bug 2: CONNECT 帧缺少 Authorization Header
|
|
||||||
|
|
||||||
**现象**: STOMP 连接后发送消息,服务端 principal 为 null,消息被静默丢弃。
|
|
||||||
**根因**: 服务端 `WebSocketConfig.java` 从 STOMP CONNECT 帧的 `Authorization` header 提取 token:
|
|
||||||
```java
|
|
||||||
String token = accessor.getFirstNativeHeader("Authorization");
|
|
||||||
```
|
|
||||||
而 Vue3 SDK 的 `connect()` 未在 CONNECT 帧中携带 `Authorization: Bearer <token>` header。
|
|
||||||
|
|
||||||
**Android SDK 对比**: Android SDK 的 `sendConnectFrame` 明确包含了:
|
|
||||||
```kotlin
|
|
||||||
"Authorization" to "Bearer $token"
|
|
||||||
```
|
|
||||||
|
|
||||||
**修复**: `ImClient.ts` 的 `connect()` 方法在构建 CONNECT 帧时添加:
|
|
||||||
```typescript
|
|
||||||
const token = getToken()
|
|
||||||
if (token) headers['Authorization'] = `Bearer ${token}`
|
|
||||||
```
|
|
||||||
|
|
||||||
**状态**: ✅ 已修复并验证
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🔴 Bug 3: connect() 中 token 未捕获,存在竞态条件
|
|
||||||
|
|
||||||
**现象**: 多客户端场景下,clientA 发送消息时使用错误的 token,导致认证失败。
|
|
||||||
**根因**: `connect()` 在 `onopen` 回调中调用 `getToken()` 获取当前 token。如果全局 token 在 clientA 连接建立前被其他客户端覆盖,clientA 会使用错误的 token 发送 CONNECT 帧。
|
|
||||||
|
|
||||||
**修复**: 在 `connect()` 方法**入口处**立即捕获 token 和 URL,后续 `onopen` 回调使用捕获值:
|
|
||||||
```typescript
|
|
||||||
connect(): void {
|
|
||||||
const token = getToken() // 立即捕获
|
|
||||||
const url = `${config.wsUrl || DEFAULT_IM_WS_URL}?token=${token ?? ''}`
|
|
||||||
// ... onopen 中使用捕获的 token
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**状态**: ✅ 已修复并验证
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🟡 Bug 4: SDKConfig 不支持自定义 baseUrl / wsUrl
|
|
||||||
|
|
||||||
**现象**: SDK 只能连接 `https://dev.xuqinmin.com`,无法切换到本地测试环境 `192.168.113.37`。
|
|
||||||
**根因**: `init()` 硬编码使用 `DEFAULT_API_BASE_URL` 和 `DEFAULT_IM_WS_URL`,未从 `SDKConfig` 读取自定义 URL。
|
|
||||||
|
|
||||||
**修复**:
|
|
||||||
- `SDKConfig` 类型添加 `baseUrl?: string` 和 `wsUrl?: string`
|
|
||||||
- `init()` 使用 `config.baseUrl || DEFAULT_API_BASE_URL`
|
|
||||||
- `ImClient.connect()` 使用 `config.wsUrl || DEFAULT_IM_WS_URL`
|
|
||||||
|
|
||||||
**状态**: ✅ 已修复并验证
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 🟡 Bug 5: 缺少 sendMessage / createGroup API 封装
|
|
||||||
|
|
||||||
**现象**: SDK 没有暴露 `sendMessage` 和 `createGroup` 函数,用户需直接调用 `http.post`。
|
|
||||||
**根因**: `api.ts` 中缺少这两个常用 API 的封装。
|
|
||||||
**修复**: 在 `src/im/api.ts` 中添加:
|
|
||||||
```typescript
|
|
||||||
export function sendMessage(params: {...}): Promise<ImMessage>
|
|
||||||
export function createGroup(params: {...}): Promise<ImGroup>
|
|
||||||
```
|
|
||||||
并在 `src/index.ts` 中导出。
|
|
||||||
|
|
||||||
**状态**: ✅ 已修复并验证
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 三、测试详情
|
|
||||||
|
|
||||||
### 3.1 单元测试
|
|
||||||
|
|
||||||
| 模块 | 测试数 | 说明 |
|
|
||||||
|------|--------|------|
|
|
||||||
| core/sdk | 7 | init, getConfig, setToken, getToken, setUserId, getUserId |
|
|
||||||
| core/http | 8 | configureHttp, buildUrl, GET/POST/PUT/DELETE, query 参数处理, Date 序列化, 错误处理 |
|
|
||||||
| im/ImClient | 15 | STOMP 连接/发送/接收/撤回/重连/断开, 事件监听/取消, messageId 生成 |
|
|
||||||
| im/useIm | 9 | Composable 状态管理, 消息增删改, 会话排序, 已读标记, 连接/断开 |
|
|
||||||
|
|
||||||
### 3.2 集成测试 (E2E)
|
|
||||||
|
|
||||||
| 模块 | 测试项 | 结果 |
|
|
||||||
|------|--------|------|
|
|
||||||
| Authentication | user_a / user_b 登录获取 token | ✅ |
|
|
||||||
| SDK Initialization | 自定义 baseUrl/wsUrl | ✅ |
|
|
||||||
| User Profile API | getProfile / updateProfile | ✅ |
|
|
||||||
| Conversations API | listConversations / markRead | ✅ |
|
|
||||||
| Message History API | fetchHistory / searchMessages | ✅ |
|
|
||||||
| Friends API | listFriends / listFriendRequests / searchUsers | ✅ |
|
|
||||||
| Groups API | listGroups / searchGroups / getGroupInfo | ✅ |
|
|
||||||
| WebSocket Connection | 双端 STOMP 连接 | ✅ |
|
|
||||||
| WebSocket Message Flow | send → history 确认 → sender echo → receiver push | ✅ |
|
|
||||||
| Read Receipt | markRead HTTP + WS READ 状态推送 | ✅ |
|
|
||||||
| Message Revoke | revoke WS + receiver revoke 事件 | ✅ |
|
|
||||||
| Conversation Management | pin / mute / draft / delete | ✅ |
|
|
||||||
| Group Operations | createGroup / fetchGroupHistory | ✅ |
|
|
||||||
| Message Edit | editMessage | ✅ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 四、Demo 应用
|
|
||||||
|
|
||||||
已创建独立 Vue3 Demo 应用:`/Users/xuqinmin/Projects/XuqmGroup/XuqmGroup-Vue3SDK-Demo/`
|
|
||||||
|
|
||||||
### 功能特性
|
|
||||||
- 快捷登录(user_a / user_b / user_ascii)
|
|
||||||
- WebSocket 实时连接状态显示
|
|
||||||
- 会话列表(含未读角标)
|
|
||||||
- 好友列表 / 群组列表
|
|
||||||
- 实时聊天(发送/接收/撤回)
|
|
||||||
- API 测试控制台(一键测试所有 API)
|
|
||||||
- 操作日志面板
|
|
||||||
|
|
||||||
### 启动方式
|
|
||||||
```bash
|
|
||||||
cd /Users/xuqinmin/Projects/XuqmGroup/XuqmGroup-Vue3SDK-Demo
|
|
||||||
npx vite
|
|
||||||
# 访问 http://localhost:5173
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 五、代码变更清单
|
|
||||||
|
|
||||||
| 文件 | 变更类型 | 说明 |
|
|
||||||
|------|----------|------|
|
|
||||||
| `src/types/index.ts` | 修改 | SDKConfig 添加 baseUrl / wsUrl |
|
|
||||||
| `src/core/sdk.ts` | 修改 | init() 支持自定义 baseUrl |
|
|
||||||
| `src/im/ImClient.ts` | 重写 | 完整 STOMP 协议实现 |
|
|
||||||
| `src/im/api.ts` | 修改 | 添加 sendMessage / createGroup |
|
|
||||||
| `src/index.ts` | 修改 | 导出新增 API |
|
|
||||||
| `package.json` | 修改 | 添加 test / test:watch / test:coverage 脚本 |
|
|
||||||
| `vitest.config.ts` | 新增 | Vitest 测试配置 |
|
|
||||||
| `__tests__/unit/core/sdk.test.ts` | 新增 | SDK 单元测试 |
|
|
||||||
| `__tests__/unit/core/http.test.ts` | 新增 | HTTP 客户端单元测试 |
|
|
||||||
| `__tests__/unit/im/ImClient.test.ts` | 新增 | ImClient 单元测试 |
|
|
||||||
| `__tests__/unit/im/useIm.test.ts` | 新增 | useIm Composable 单元测试 |
|
|
||||||
| `__tests__/integration/e2e.node.mjs` | 新增 | Node.js 端到端集成测试 |
|
|
||||||
| `XuqmGroup-Vue3SDK-Demo/` | 新增 | Vue3 Demo 应用 |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 六、服务端观察(非 SDK Bug)
|
|
||||||
|
|
||||||
在测试过程中,对服务端 `im-service` 的 `WebSocketConfig.java` 进行了代码审查:
|
|
||||||
|
|
||||||
```java
|
|
||||||
String token = accessor.getFirstNativeHeader("Authorization");
|
|
||||||
if (token != null && token.startsWith("Bearer ")) {
|
|
||||||
token = token.substring(7);
|
|
||||||
if (jwtUtil.isValid(token)) {
|
|
||||||
String userId = jwtUtil.getSubject(token);
|
|
||||||
...
|
|
||||||
accessor.setUser(auth);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
**观察**: 服务端仅从 STOMP header 读取 Authorization,不支持 URL query param `?token=xxx`。这是合理的设计(STOMP 规范推荐),但需在 SDK 文档中明确说明:**WebSocket 认证必须通过 CONNECT 帧的 `Authorization` header 传递**。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 七、下一步建议
|
|
||||||
|
|
||||||
1. **发布新版 SDK**: 当前修复包含重大协议变更(自定义 JSON → STOMP),建议发布新版本。
|
|
||||||
2. **更新官方文档**: 在 README 中补充 `baseUrl` / `wsUrl` 配置说明。
|
|
||||||
3. **Tenant Platform 集成**: 已在 tenant-platform 目录结构中找到 IM 管理页面,建议将 Vue3 SDK 集成到 `tenant-platform` 中作为管理员 IM 测试工具。
|
|
||||||
4. **CI/CD 集成**: 将 `npm run test` 和 `node __tests__/integration/e2e.node.mjs` 纳入 Jenkins 流水线。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
> **测试结论**: Vue3 SDK 经过全面测试和修复,HTTP API 和 WebSocket 实时消息流均工作正常,所有 75 项测试通过。
|
|
||||||
279
docs/DEPLOY.md
279
docs/DEPLOY.md
@ -1,279 +0,0 @@
|
|||||||
# 部署文档
|
|
||||||
|
|
||||||
## 一、基础设施要求
|
|
||||||
|
|
||||||
| 组件 | 版本 | 说明 |
|
|
||||||
|------|------|------|
|
|
||||||
| 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"}`
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
# 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` |
|
|
||||||
正在加载...
在新工单中引用
屏蔽一个用户