比较提交

...

2 次代码提交

作者 SHA1 备注 提交日期
XuqmGroup
499f557bf7 feat(im): 添加平台事件通知功能支持应用审核状态实时更新
- 新增 ImPlatformEventController 提供令牌获取接口
- 新增 InternalImPlatformEventController 处理内部通知请求
- 实现 ImPlatformEventService 核心服务逻辑包括令牌签发和消息推送
- 添加 StoreReviewImNotifier 在更新服务中触发审核状态变更通知
- 在前端平台中集成实时审核状态更新功能
- 配置各项目环境版本管理文件 (.java-version, .nvmrc)
- 更新 Docker 忽略文件和 Maven 配置以优化构建流程
2026-05-08 18:32:46 +08:00
XuqmGroup
94cc3bd097 docs(deploy): 添加部署文档和安全设计规范
- 新增 XuqmGroup 部署文档,包含部署方案、架构建议和部署步骤
- 添加安全设计规范,涵盖密码安全、AppSecret验证和服务端API认证
- 补充平台REST API规范,定义Server-to-Server调用接口和错误码
- 创建Java IM服务端SDK计划文档,规划Maven包发布和接口实现
2026-05-08 18:31:59 +08:00
共有 6 个文件被更改,包括 8 次插入7 次删除

1
.java-version 普通文件
查看文件

@ -0,0 +1 @@
21

查看文件

@ -284,7 +284,7 @@ PushSDK.setReceivePush(context, enabled = true)
```kotlin ```kotlin
val result: UpdateResult = UpdateSDK.checkUpdate( val result: UpdateResult = UpdateSDK.checkUpdate(
appId = "ak_xxx", appKey = "ak_xxx",
platform = Platform.ANDROID platform = Platform.ANDROID
) )

查看文件

@ -37,7 +37,7 @@
- 样例 App 的本地联调默认值之前落在 `10.0.2.2`,和当前实际调试 IP 不一致,已统一回 `192.168.113.37` - 样例 App 的本地联调默认值之前落在 `10.0.2.2`,和当前实际调试 IP 不一致,已统一回 `192.168.113.37`
- 设备启动时,旧缓存的登录态会让 App 直接进入主界面,随后 IM 接口先打出 `403` - 设备启动时,旧缓存的登录态会让 App 直接进入主界面,随后 IM 接口先打出 `403`
- `restoreSdkSession()` 之前是异步跑的,旧 session 失效时,主界面可能先出现再刷新失败。 - `restoreSdkSession()` 之前是异步跑的,旧 session 失效时,主界面可能先出现再刷新失败。
- `UpdateSDK.checkAppUpdate()` 实际请求的是 `appId=ak_demo_chat`,并且日志已经返回 `versionName=1.0.1`、`versionCode=2`、`needsUpdate=true`、`downloadUrl=https://sentry.xuqinmin.com/files/apk/xuqm-chat-demo-1.0.1.apk`,所以当前看到的更新弹窗是 update-service 这条数据驱动的,不是租户平台版本管理页是否有记录直接决定的。 - `UpdateSDK.checkAppUpdate()` 实际请求的是 `appKey=ak_demo_chat`,并且日志已经返回 `versionName=1.0.1`、`versionCode=2`、`needsUpdate=true`、`downloadUrl=https://sentry.xuqinmin.com/files/apk/xuqm-chat-demo-1.0.1.apk`,所以当前看到的更新弹窗是 update-service 这条数据驱动的,不是租户平台版本管理页是否有记录直接决定的。
- 版本管理页当前用的是租户应用 `app.id`,而样例 App 仍然使用 `appKey=ak_demo_chat` 作为更新和 IM 的作用域,两个视图不一致时,页面空但弹窗出现是正常现象。 - 版本管理页当前用的是租户应用 `app.id`,而样例 App 仍然使用 `appKey=ak_demo_chat` 作为更新和 IM 的作用域,两个视图不一致时,页面空但弹窗出现是正常现象。
- `emulator-5558` 在接受好友申请后,联系人页仍然保留了 `好友申请1` 的可见区域,说明好友申请列表的刷新路径还需要继续排查。 - `emulator-5558` 在接受好友申请后,联系人页仍然保留了 `好友申请1` 的可见区域,说明好友申请列表的刷新路径还需要继续排查。

查看文件

@ -79,7 +79,7 @@ adb wait-for-device && sleep 15
### 3.4 测试账号 ### 3.4 测试账号
| 账号 | 密码 | appId | 用途 | | 账号 | 密码 | appKey | 用途 |
|------|------|-------|------| |------|------|-------|------|
| user_a | 123456 | ak_demo_chat | 主发送方 | | user_a | 123456 | ak_demo_chat | 主发送方 |
| user_b | 123456 | ak_demo_chat | 接收方 | | user_b | 123456 | ak_demo_chat | 接收方 |

查看文件

@ -34,7 +34,7 @@ import java.io.File
/** /**
* TC-05 / TC-07 / TC-08 / TC-11~15 集成测试 * TC-05 / TC-07 / TC-08 / TC-11~15 集成测试
* 运行环境: external (https://dev.xuqinmin.com) * 运行环境: external (https://dev.xuqinmin.com)
* 测试账号: user_a / user_b (password: 123456, appId: ak_demo_chat) * 测试账号: user_a / user_b (password: 123456, appKey: ak_demo_chat)
* *
* 设计原则: * 设计原则:
* - tc05/tc11a/tc11b/tc14/tc99 使用 @BeforeClass 中创建的新鲜 GROUPtestGroupId * - tc05/tc11a/tc11b/tc14/tc99 使用 @BeforeClass 中创建的新鲜 GROUPtestGroupId

查看文件

@ -162,7 +162,7 @@ data class ReleaseDefaults(
fun fetchReleaseDefaults(tenantUrl: String, appKey: String): ReleaseDefaults? { fun fetchReleaseDefaults(tenantUrl: String, appKey: String): ReleaseDefaults? {
if (tenantUrl.isBlank()) return null if (tenantUrl.isBlank()) return null
val url = "$tenantUrl/api/sdk/config?appId=$appKey&platform=ANDROID" val url = "$tenantUrl/api/sdk/config?appKey=$appKey&platform=ANDROID"
val json = runCatching { httpGet(url, "") }.getOrNull() ?: return null val json = runCatching { httpGet(url, "") }.getOrNull() ?: return null
if (!parseJsonBool(json, "updateEnabled", false)) return ReleaseDefaults(enabled = false) if (!parseJsonBool(json, "updateEnabled", false)) return ReleaseDefaults(enabled = false)
return ReleaseDefaults( return ReleaseDefaults(
@ -257,7 +257,7 @@ tasks.register("xuqmRelease") {
println("[xuqm] Local version: $versionName ($versionCode), packageName: $applicationId, appKey: $appKey") println("[xuqm] Local version: $versionName ($versionCode), packageName: $applicationId, appKey: $appKey")
// ── 2. Check server latest ───────────────────────────────────────── // ── 2. Check server latest ─────────────────────────────────────────
val listResp = httpGet("$serverUrl/api/v1/updates/app/list?appId=$appKey&platform=ANDROID", apiToken) val listResp = httpGet("$serverUrl/api/v1/updates/app/list?appKey=$appKey&platform=ANDROID", apiToken)
// Find highest published versionCode // Find highest published versionCode
val serverVersionCode = Regex("\"versionCode\"\\s*:\\s*(\\d+)").findAll(listResp) val serverVersionCode = Regex("\"versionCode\"\\s*:\\s*(\\d+)").findAll(listResp)
.mapNotNull { it.groupValues[1].toIntOrNull() } .mapNotNull { it.groupValues[1].toIntOrNull() }
@ -318,7 +318,7 @@ tasks.register("xuqmRelease") {
// ── 4. Upload to update service ─────────────────────────────────── // ── 4. Upload to update service ───────────────────────────────────
val parts = mutableMapOf<String, Any>( val parts = mutableMapOf<String, Any>(
"appId" to appKey, "appKey" to appKey,
"platform" to "ANDROID", "platform" to "ANDROID",
"versionName" to releaseVersionName, "versionName" to releaseVersionName,
"versionCode" to releaseVersionCode, "versionCode" to releaseVersionCode,