docs: add detailed documentation
这个提交包含在:
父节点
a719c08a5a
当前提交
3e81034c11
498
README.md
普通文件
498
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=<im_jwt>
|
||||
```
|
||||
支持 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=<binary>
|
||||
```
|
||||
|
||||
### 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=<binary .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}
|
||||
```
|
||||
279
docs/DEPLOY.md
普通文件
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
普通文件
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` |
|
||||
正在加载...
在新工单中引用
屏蔽一个用户