XuqmGroup-Server/README.md

12 KiB

XuqmGroup-Server 后端文档

当前推荐阅读入口:/docs/server/README.md
仓库内联调文档:docs/API_ACCESS.md
该文档保留为仓库内说明,线上地址、初始化账号与最新联调接口请以最新文档为准。

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 实时通信

快速启动

# 前置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= 重置密码

注册请求体

{
  "username": "demo",
  "password": "Demo@123456",
  "email": "demo@example.com",
  "nickname": "Demo",
  "emailCode": "AB3K"
}

登录请求体

{
  "account": "demo",
  "password": "Demo@123456",
  "captchaKey": "uuid-from-captcha-api",
  "captchaCode": "XK2P"
}

登录响应

{
  "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} 删除应用

创建应用请求体

{
  "name": "我的App",
  "packageName": "com.example.myapp",
  "description": "描述",
  "iconUrl": "https://cdn.example.com/icon.png"
}

应用对象(响应)

{
  "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 生成随机密码

创建子账号请求体

{
  "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 获取统计数据

运营登录请求体

{ "username": "admin", "password": "Admin@123456" }

统计响应

{
  "data": {
    "totalTenants": 128,
    "todayNew": 5,
    "activeApps": 42,
    "onlineUsers": 0
  }
}

im-serviceIM 服务):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= 查询历史消息

发送消息请求体

{
  "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

发送消息(客户端 → 服务端)

{
  "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 格式:

{
  "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"
  }
}

撤回消息(客户端 → 服务端)

{
  "destination": "/app/chat.revoke",
  "payload": { "appId": "ak_xxx", "messageId": "msg-uuid" }
}

撤回推送(服务端 → 客户端)

{
  "type": "REVOKE",
  "payload": { "msgId": "msg-uuid", "operatorId": "user_001" }
}

关键词过滤

im_keyword_filter 表中配置,支持 REPLACE(替换为 *)和 BLOCK拒绝发送两种动作,pattern 为正则表达式。

Webhook

im_webhook_config 表中为 App 配置 URL,消息发送后异步 HTTP POST 通知,超时 3000ms,格式

{
  "event": "message",
  "appId": "ak_xxx",
  "message": { ...消息对象... }
}

push-service推送服务:8083

数据库表

表名 说明
push_device_token 设备推送 tokenappId + userId + vendor 唯一)

支持厂商

HUAWEI / XIAOMI / OPPO / VIVO / HONOR / APNSiOS/ 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"}

环境变量配置

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
  &currentVersionCode=10

响应(有更新):

{
  "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

上传 APKmultipart/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
  &currentVersion=1.0.0

响应(有更新):

{
  "data": {
    "needsUpdate": true,
    "latestVersion": "1.1.0",
    "downloadUrl": "http://...",
    "md5": "abc123...",
    "minCommonVersion": "1.0.0",
    "note": "热更新说明"
  }
}

上传 Bundlemultipart/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}/

环境变量配置

update:
  upload-dir: ${UPDATE_UPLOAD_DIR:/tmp/xuqm-update}
  base-url: ${UPDATE_BASE_URL:http://localhost:8084}